Sobes.tech
Middle

C++'ta akıllı işaretçiler hakkında ne biliyorsunuz?

sobes.tech yapay zeka

AI'dan gelen yanıt

Akıllı işaretçiler, C++'daki normal (ham) işaretçiler üzerinde RAII sarmalayıcılarıdır ve tahsis edilen belleğin yaşam süresini otomatik olarak yöneterek sızıntıları önler.

C++ standart kütüphanesinde temel akıllı işaretçi türleri:

  • std::unique_ptr
  • std::shared_ptr
  • std::weak_ptr

std::unique_ptr

  • Kaynağı münhasıran sahiplenir.
  • Kopyalanamaz, ancak taşınabilir.
  • Kaynağın tek sahiplenilmesi için kullanılır.
  • Ek maliyetler minimaldir, ham işaretçiye eşdeğerdir.
// unique_ptr örneği
#include <memory>
#include <iostream>

int main() {
    std::unique_ptr<int> ptr = std::make_unique<int>(10);
    std::cout << *ptr << std::endl; // 10
    // std::unique_ptr<int> ptr2 = ptr; // Derleme hatası: unique_ptr kopyalanamaz
    std::unique_ptr<int> ptr3 = std::move(ptr); // Sahipliği taşıma
    std::cout << *ptr3 << std::endl; // 10
    // std::cout << *ptr << std::endl; // Tanımsız davranış: ptr artık boş
    return 0;
}

std::shared_ptr

  • Birden fazla işaretçinin aynı kaynağı ortaklaşa sahiplenmesine izin verir.
  • Referans sayacı kullanır. Sayaç sıfıra düştüğünde bellek serbest bırakılır.
  • Kopyalanabilir. Her kopya referans sayacını artırır.
  • unique_ptr'a göre daha yüksek maliyetlidir, çünkü sayaç yönetimi gerektirir.
// shared_ptr örneği
#include <memory>
#include <iostream>

int main() {
    std::shared_ptr<int> ptr1 = std::make_shared<int>(20);
    std::cout << *ptr1 << " (use_count: " << ptr1.use_count() << ")" << std::endl; // 20 (use_count: 1)
    std::shared_ptr<int> ptr2 = ptr1; // Kopya, use_count artar
    std::cout << *ptr1 << " (use_count: " << ptr1.use_count() << ")" << std::endl; // 20 (use_count: 2)
    std::shared_ptr<int> ptr3 = ptr1; // Başka bir kopya
    std::cout << *ptr1 << " (use_count: " << ptr1.use_count() << ")" << std::endl; // 20 (use_count: 3)
    return 0;
}

std::weak_ptr

  • Kaynağı sahiplenmez ve referans sayacını artırmaz.
  • shared_ptr arasındaki döngüsel referans sorununu çözmek için kullanılır.
  • shared_ptr'ın gösterdiği kaynağa erişim sağlar, ancak onun silinmesini engellemez.
  • Kaynağa erişmek için weak_ptrshared_ptr'a dönüştürmek gerekir, lock() yöntemi kullanılarak.
// weak_ptr örneği
#include <memory>
#include <iostream>

int main() {
    std::shared_ptr<int> shared_ptr_int = std::make_shared<int>(30);
    std::weak_ptr<int> weak_ptr_int = shared_ptr_int;

    if (auto locked_ptr = weak_ptr_int.lock()) {
        std::cout << *locked_ptr << std::endl; // 30
    } else {
        std::cout << "Kaynak serbest bırakıldı." << std::endl;
    }

    shared_ptr_int.reset(); // Kaynak serbest bırakılır

    if (auto locked_ptr = weak_ptr_int.lock()) {
        std::cout << *locked_ptr << std::endl;
    } else {
        std::cout << "Kaynak serbest bırakıldı." << std::endl; // Kaynak serbest bırakıldı.
    }
    return 0;
}

Akıllı işaretçilerin kullanımı modern C++'ta iyi bir uygulamadır, çünkü bellek yönetimi hatası olasılığını önemli ölçüde azaltır.