LuvyAI — Ücretsiz başla. 18+

MODERN ISO C++ PROGRAMLAMA DERSLERİ: BÖLÜM 3 🚀 Move Semantics, Perfect Forwarding, Rule of 0/3/5 & RAII Mimarısı

/*
================================================================================
🚀 MODERN ISO C++ PROGRAMLAMA DERSLERİ: BÖLÜM 3 🚀
Move Semantics, Perfect Forwarding, Rule of 0/3/5 & RAII Mimarısı
================================================================================

GİRİŞ 📌
--------------------------------------------------------------------------------
İkinci bölümde Lvalue/Rvalue ayrımını, referans semantiğini, auto/decltype
tip çıkarım kurallarını ve `constexpr` yapısını incelemiştik.

Bu bölümde ise Modern C++'ı (C++11 ve sonrası) C++98'den ayıran en büyük devrim
olan **Taşıma Semantiği (Move Semantics)**, esnek ve performanslı şablon tasarımı
için **Perfect Forwarding**, güvenli kaynak yönetimi sağlayan **RAII** ilkesi ve
nesne yaşam döngüsünü yöneten **Rule of 0 / 3 / 5** kurallarını ele alacağız.
*/

#include <iostream>
#include <utility>

// =============================================================================
// 1. RAII (RESOURCE ACQUISITION IS INITIALIZATION) VE KAZANÇLARI 🛡️
// =============================================================================
/*
* RAII, C++'ın en temel bellek ve kaynak yönetim ilkesidir:
* 1. Kaynak (bellek, dosya, socket, mutex vb.) kurucu fonksiyonda (constructor) edinilir.
* 2. Kaynak, yıkıcı fonksiyonda (destructor) otomatik olarak serbest bırakılır.
* 3. Stack üstündeki nesnelerin yıkıcıları kapsam (scope) sonlandığında istisna
* (exception) fırlatılsa dahi GARANTİ olarak çağrılır (Stack Unwinding).
*/

class DynamicBuffer {
private:
std::size_t m_size;
int* m_data;

public:
// Kurucu Fonksiyon (Constructor) - Kaynak Edinimi
explicit DynamicBuffer(std::size_t size)
: m_size(size), m_data(new int[size]{}) {
std::cout << "📦 Buffer olusturuldu (Size: " << m_size << ")\n";
}

// Yıkıcı Fonksiyon (Destructor) - Kaynak Serbest Bırakma
~DynamicBuffer() noexcept {
delete[] m_data;
std::cout << "🧹 Buffer bellegi temizlendi.\n";
}

// =========================================================================
// 2. RULE OF 5: KOPYALAMA VE TAŞIMA OPERATÖRLERİ ⚙️
// =========================================================================
/*
* Eğer bir sınıf ham bir kaynak (pointer, file handle vb.) yönetiyorsa,
* ISO C++ standartlarına göre şu 5 özel üye fonksiyonu tanımlamalıdır:
* 1. Destructor
* 2. Copy Constructor
* 3. Copy Assignment Operator
* 4. Move Constructor
* 5. Move Assignment Operator
*/

// A) Copy Constructor (Derin Kopyalama / Deep Copy - Pahalı İşlem)
DynamicBuffer(const DynamicBuffer& other)
: m_size(other.m_size), m_data(new int[other.m_size]) {
for (std::size_t i = 0; i < m_size; ++i) {
m_data = other.m_data;
}
std::cout << "📋 Copy Constructor çağrıldı (Derin Kopyalama)\n";
}

// B) Copy Assignment Operator
DynamicBuffer& operator=(const DynamicBuffer& other) {
if (this != &other) {
delete[] m_data; // Eski kaynağı serbest bırak

m_size = other.m_size;
m_data = new int[m_size];
for (std::size_t i = 0; i < m_size; ++i) {
m_data = other.m_data;
}
}
std::cout << "📋 Copy Assignment çağrıldı\n";
return *this;
}

// C) Move Constructor (Sahiplik Transferi / Ownership Transfer - Ucuz İşlem)
// NOT: Move işlemleri 'noexcept' işaretlenmelidir; aksi halde std::vector
// gibi STL kapsayıcıları güvenli taşıma yapamaz ve kopyalamaya düşer!
DynamicBuffer(DynamicBuffer&& other) noexcept
: m_size(other.m_size), m_data(other.m_data) {
// Kaynakçalının (other) işaretçisini sıfırla ki yıkıcısı belleği silmesin!
other.m_size = 0;
other.m_data = nullptr;
std::cout << "🚀 Move Constructor çağrıldı (Sahiplik Aktarıldı)\n";
}

// D) Move Assignment Operator
DynamicBuffer& operator=(DynamicBuffer&& other) noexcept {
if (this != &other) {
delete[] m_data; // Mevcut kaynağı temizle

m_size = other.m_size;
m_data = other.m_data;

other.m_size = 0;
other.m_data = nullptr;
}
std::cout << "🚀 Move Assignment çağrıldı\n";
return *this;
}

std::size_t size() const noexcept { return m_size; }
};


// =============================================================================
// 3. UNIVERSAL REFERENCES VE PERFECT FORWARDING (`std::forward`) 🔄
// =============================================================================
/*
* Şablon parametrelerinde `T&&` ifadesi Universal Reference (veya Forwarding Ref)
* olarak adlandırılır. Kendisine geçilen argümanın Lvalue veya Rvalue olma
* durumunu korur (Reference Collapsing kuralları sayesinde).
*
* `std::forward<T>` kullanarak bu argümanı hedefe aynen (orijinal değer kategorisiyle)
* iletmeye "Perfect Forwarding" denir.
*/

class Widget {
public:
Widget() = default;
};

void make_work(Widget& w) {
std::cout << "🛠️ Work yapılıyor: Lvalue Widget\n";
}

void make_work(Widget&& w) {
std::cout << "🛠️ Work yapılıyor: Rvalue Widget (Geçici Nesne)\n";
}

template<typename T>
void relay(T&& arg) { // Universal Reference
// std::forward<T> argümanın Lvalue mi Rvalue mi olduğunu koruyarak iletir:
make_work(std::forward<T>(arg));
}

void demonstrate_forwarding() {
Widget w;
relay(w); // Lvalue iletir -> make_work(Widget&) çağrılır
relay(Widget()); // Rvalue iletir -> make_work(Widget&&) çağrılır
relay(std::move(w)); // Rvalue iletir -> make_work(Widget&&) çağrılır
}


// =============================================================================
// 4. MAIN VE TEST SENARYOLARI 🚀
// =============================================================================

int main() {
std::cout << "============================================" << std::endl;
std::cout << " ISO C++17/20/23 Dersleri - Bolum 3 " << std::endl;
std::cout << "============================================" << std::endl << std::endl;

std::cout << "--- 1. RAII ve Move Semantics ---" << std::endl;
{
DynamicBuffer buf1(1024); // Normal allocation

DynamicBuffer buf2 = buf1; // Copy Constructor (Ağır kopyalama)

// std::move: buf1'i Rvalue'ya dönüştürür ve taşıma semantiğini tetikler.
DynamicBuffer buf3 = std::move(buf1); // Move Constructor (Hızlı transfer)

std::cout << "buf1 size: " << buf1.size() << " (Boşaltıldı)\n";
std::cout << "buf3 size: " << buf3.size() << " (Kaynak devralındı)\n";
} // Tüm nesneler otomatik olarak yıkılır!

std::cout << "\n--- 2. Perfect Forwarding ---" << std::endl;
demonstrate_forwarding();

std::cout << "\n✔ Bolum 3 Kavramlari Başariyla İslendi!" << std::endl;

return 0;
}

/*
================================================================================
BÖLÜM ÖZETİ VE GELECEK BÖLÜM 📝
--------------------------------------------------------------------------------
Bu bölümde bellek yönetimi ve performansın kalbi olan RAII ilkesini, Rule of 5
yapısını, Move Semantics mantığını ve Perfect Forwarding mekanizmasını inceledik.

Gelecek Bölüm (Bölüm 4):
- Smart Pointers Mimarısı: `std::unique_ptr`, `std::shared_ptr`, `std::weak_ptr` 🧠
- Custom Deleters & Control Block İç Yapısı ⚙️
- Circular Reference (Döngüsel Bağımlılık) Problemi ve Çözümü 🔄
- Modern Bellek Yönetiminde `std::make_unique` ve `std::make_shared` Kullanımı
=====
===========================================================================
Bölüm 3 Sonu.
================================================================================
*/

🔒 Bu içeriği görmek için giriş yapın

 
Yanıt yazmak için giriş yapmalısınız
Forum özelliklerini kullanmak ve Level 2 üyelik satın almak için hesabınıza giriş yapın.
136,861Threads
3,308,879Messages
328,700Members
hyper10nLatest member
Top Bottom