MODERN ISO C++ PROGRAMLAMA DERSLERİ: BÖLÜM 4 🚀 Smart Pointers Mimarısı: std::unique_ptr, std::shared_ptr, std::weak_ptr

/*
================================================================================
🚀 MODERN ISO C++ PROGRAMLAMA DERSLERİ: BÖLÜM 4 🚀
Smart Pointers Mimarısı: std::unique_ptr, std::shared_ptr, std::weak_ptr
================================================================================

GİRİŞ 📌
--------------------------------------------------------------------------------
Üçüncü bölümde RAII ilkesini, Rule of 0/3/5 kurallarını, Move Semantics ve
Perfect Forwarding mekanizmalarını incelemiştik.

Bu bölümde modern C++'ta manuel bellek yönetimini (new/delete) tamamen rafa
kaldıran **Akıllı İşaretçileri (Smart Pointers)**, bunların bellek mimarisini,
`std::shared_ptr` arkasındaki **Control Block** yapısını, dairesel referans
(Circular Reference) problemini ve çözümlerini ele alacağız.
*/

#include <iostream>
#include <memory>
#include <string>

// =============================================================================
// 1. `std::unique_ptr`: TEKİL SAHİPLİK VE SIFIR MALİYET ABSTRAKSİYONU 🔒
// =============================================================================
/*
* `std::unique_ptr`, yönettiği kaynağın TEK SAHİBİDİR.
* - Kopyalanamaz (Copy Constructor / Assignment silinmiştir = `= delete`).
* - Yalnızca TAŞINABİLİR (Move Only).
* - Sıfır Çalışma Zamanı Maliyeti (Zero-overhead abstraction): Ham bir pointer
* ile aynı bellek boyutuna (`sizeof(unique_ptr) == sizeof(void*)`) sahiptir.
*/

struct Device {
std::string name;
explicit Device(std::string n) : name(std::move(n)) {
std::cout << "🔌 Device Donanimi Başlatildi: " << name << "\n";
}
~Device() {
std::cout << "💀 Device Donanimi Kapatildi: " << name << "\n";
}
void execute() const {
std::cout << "⚙️ " << name << " komut calistiriyor...\n";
}
};

void demonstrate_unique_ptr() {
// std::make_unique kullanımı (ISO C++14): Exception-safe ve tek allocation.
auto dev = std::make_unique<Device>("FPGA_Board_V1");
dev->execute();

// std::unique_ptr<Device> dev2 = dev; // ❌ HATA: Kopyalanamaz!

// Sahiplik aktarımı (Move Semantics):
std::unique_ptr<Device> dev2 = std::move(dev);
if (!dev) {
std::cout << "📌 'dev' artik nullptr; sahiplik 'dev2'ye gecti.\n";
}
dev2->execute();
} // Scope sonunda 'dev2' otomatik olarak Device'ı imha eder!


// =============================================================================
// 2. `std::shared_ptr` VE CONTROL BLOCK BİLLEK MİMARİSİ 🧠
// =============================================================================
/*
* `std::shared_ptr`, paylaşımlı sahiplik (shared ownership) sağlar.
*
* CONTROL BLOCK MİMARİSİ:
* `std::shared_ptr` arka planda iki adet işaretçi tutar (sizeof = 2 * sizeof(void*)):
* 1. Ptr to Object (Nesne İşaretçisi)
* 2. Ptr to Control Block (Heap'te tahsis edilen Kontrol Bloğu)
*
* ┌────────────────────────────────────────────────────────┐
* │ CONTROL BLOCK │
* ├──────────────────────────┬─────────────────────────────┤
* │ Strong Ref Count (2) │ Weak Ref Count (1) │
* ├──────────────────────────┼─────────────────────────────┤
* │ Custom Deleter (opt) │ Custom Allocator (opt) │
* └──────────────────────────┴─────────────────────────────┘
*
* - Reference Counting işlemleri ATOMIK'tir (Thread-safe ref count artırımı/azaltımı).
* - `std::make_shared` kullanımı, nesne ile Control Block'u TEK BİR HEAP ALLOCATION
* içinde birleştirerek performans ve bellek yerelliği (cache locality) sağlar.
*/

void demonstrate_shared_ptr() {
std::shared_ptr<Device> sp1 = std::make_shared<Device>("GPU_Cluster_Node");
std::cout << "Ref Count (sp1): " << sp1.use_count() << "\n"; // 1

{
std::shared_ptr<Device> sp2 = sp1; // Kopyalama -> Ref count artar
std::cout << "Ref Count (sp1 & sp2 scope ici): " << sp1.use_count() << "\n"; // 2
} // sp2 imha oldu -> Ref count azalır

std::cout << "Ref Count (sp1 scope disi): " << sp1.use_count() << "\n"; // 1
}


// =============================================================================
// 3. DAİRESEL REFERANS (CIRCULAR REFERENCE) VE `std::weak_ptr` 🔄
// =============================================================================
/*
* Eğer iki `std::shared_ptr` birbirini karşılıklı olarak referans ederse,
* Strong Ref Count hiçbir zaman 0'a düşmez ve BELLEK SIZINTISI (Memory Leak) oluşur.
*
* ÇÖZÜM: `std::weak_ptr`
* - Sahiplik İDDİASINDA BULUNMAZ (Strong Ref Count'ı artırmaz).
* - Control Block'taki Weak Ref Count'ı artırır.
* - Nesneye erişmek için `lock()` metodu ile geçici bir `std::shared_ptr` üretilir.
*/

struct Node {
std::string name;
std::shared_ptr<Node> next;

// Dairesel bağımlılığı kırmak için weak_ptr kullanıyoruz:
std::weak_ptr<Node> prev;

explicit Node(std::string n) : name(std::move(n)) {}
~Node() { std::cout << "🗑️ Node silindi: " << name << "\n"; }
};

void demonstrate_circular_reference_fix() {
auto nodeA = std::make_shared<Node>("Node_A");
auto nodeB = std::make_shared<Node>("Node_B");

nodeA->next = nodeB; // A -> B
nodeB->prev = nodeA; // B -> A (weak_ptr sayesinde döngü kırıldı!)

// weak_ptr ile veriye güvenli erişim:
if (auto shared_prev = nodeB->prev.lock()) {
std::cout << "🔗 Node_B'nin prev dügümü: " << shared_prev->name << "\n";
} else {
std::cout << "❌ Nesne halihazirda imha edilmis!\n";
}
} // İki düğüm de sorunsuz bir şekilde bellekten temizlenir!


// =============================================================================
// 4. MAIN VE PROGRAM GİRİŞ NOKTASI 🚀
// =============================================================================

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

std::cout << "--- 1. std::unique_ptr Demo ---" << std::endl;
demonstrate_unique_ptr();

std::cout << "\n--- 2. std::shared_ptr Demo ---" << std::endl;
demonstrate_shared_ptr();

std::cout << "\n--- 3. std::weak_ptr & Circular Ref Fix ---" << std::endl;
demonstrate_circular_reference_fix();

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

return 0;
}

/*
================================================================================
BÖLÜM ÖZETİ VE GELECEK BÖLÜM 📝
--------------------------------------------------------------------------------
Bu bölümde Modern C++ bellek yönetiminin temel taşları olan `std::unique_ptr`,
`std::shared_ptr`, Control Block iç yapısı ve `std::weak_ptr` çözümlerini inceledik.

Gelecek Bölüm (Bölüm 5):
- STL (Standard Template Library) Mimarısı & Kapsayıcılar (Containers) 📦
- Sequence Containers: `std::vector` (kümeleme & büyüme stratejisi), `std::deque`
- Associative & Unordered Containers: `std::map` (Red-Black Tree) vs `std::unordered_map` (Hash Table)
- Custom Hash Function & Heterogeneous Lookup (ISO C++14/20)
===========================================================================
=====
Bölüm 4 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.
135,050Konular
3,297,704Mesajlar
326,236Kullanıcılar
KemalseSon Üye
Üst Alt