Menu
Coddy logo textTech

C++'ta Akıllı İşaretçiler

Coddy'nin C++ Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası — ders 15 / 104.

Akıllı işaretçiler (smart pointers), yığın (heap) belleğini sizin için otomatik olarak yöneten sarmalayıcı sınıflardır. İşaretçi kapsam dışına çıktığında belleği temizleyerek manuel delete çağrılarına olan ihtiyacı ortadan kaldırırlar.

Akıllı işaretçileri kullanmak için <memory> başlığını dahil edin.

unique_ptr - münhasır sahiplik. Bir kaynağa aynı anda yalnızca bir işaretçi sahip olabilir.

#include <memory>

std::unique_ptr<Player> player = std::make_unique<Player>("Hero");
player->attack();  // Normal bir işaretçi gibi kullanın

// Kopyalanamaz, ancak sahiplik devredilebilir
std::unique_ptr<Player> player2 = std::move(player);
// player artık nullptr'dir

shared_ptr - paylaşılan sahiplik. Birden fazla işaretçi aynı kaynağa sahip olabilir. Son sahip yok edildiğinde bellek serbest bırakılır.

std::shared_ptr<Player> p1 = std::make_shared<Player>("Hero");
std::shared_ptr<Player> p2 = p1;  // Her ikisi de kaynağa sahiptir

std::cout << p1.use_count();  // 2 yazdırır

weak_ptr - bir shared_ptr'nin sahiplik yapmayan gözlemcisidir. Döngüsel referansları (circular references) kırmak için yararlıdır.

std::shared_ptr<Player> shared = std::make_shared<Player>("Hero");
std::weak_ptr<Player> weak = shared;

if (auto locked = weak.lock()) {  // shared_ptr'a dönüştür
    locked->attack();
}

Tekil sahiplik için varsayılan olarak unique_ptr kullanın. Birden fazla nesnenin bir kaynağı paylaşması gerektiğinde shared_ptr kullanın. Yaşam süresini uzatmadan gözlemlemek için weak_ptr kullanın.

Ham new yerine make_unique ve make_shared kullanmayı tercih edin.

challenge icon

Görev

Kolay

Akıllı işaretçilerin (smart pointers) farklı sahiplik modellerini gösteren bir belge paylaşım sistemi oluşturalım. unique_ptr'ın özel sahipliği nasıl zorunlu kıldığını, shared_ptr'ın birden fazla sahibe nasıl izin verdiğini ve weak_ptr'ın yaşam süresini etkilemeden nasıl gözlem yapabildiğini göreceksiniz.

Kodunuzu düzenlemek için iki dosya oluşturacaksınız:

  • Document.h: Paylaşılabilir bir belgeyi temsil eden bir Document sınıfı tanımlayın. Şunlara sahip olmalıdır:
    • Özel (private) bir title özniteliği (string)
    • Bir başlık alan ve "Document created: <title>" yazdıran bir yapıcı (constructor)
    • "Document deleted: <title>" yazdıran bir yıkıcı (destructor)
    • Başlığı döndüren bir getTitle() metodu
  • main.cpp: Girişten bir belge başlığı okuyarak her üç akıllı işaretçi türünü de gösterin, ardından:
    • Giriş başlığıyla bir Document'a unique_ptr oluşturun
    • "Unique owner: <title>" yazdırın
    • std::move kullanarak sahipliği başka bir unique_ptr'a aktarın
    • "Ownership transferred" yazdırın
    • "SharedDoc" başlığıyla yeni bir Document'a shared_ptr oluşturun
    • Aynı belgeyi işaret eden ikinci bir shared_ptr oluşturun
    • use_count() kullanarak "Shared owners: <count>" yazdırın
    • Paylaşılan işaretçilerden birinden bir weak_ptr oluşturun
    • Zayıf işaretçi aracılığıyla belgeye erişmek için lock() kullanın ve "Weak access: <title>" yazdırın

Akıllı işaretçiler için <memory> kütüphanesini dahil etmeyi unutmayın. Akıllı işaretçilerinizi oluşturmak için std::make_unique ve std::make_shared kullanın. Yıkıcı mesajları, programın sonunda her belgenin ne zaman otomatik olarak temizlendiğini görmenize yardımcı olacaktır.

Başlık dosyanızı main.cpp içinde #include "Document.h" kullanarak dahil edin.

Kopya kağıdı

Akıllı işaretçiler (smart pointers), yığın (heap) belleğini otomatik olarak yöneten sarmalayıcı sınıflardır. Bunları kullanmak için <memory> başlık dosyasını dahil edin.

unique_ptr

Özel sahiplik - bir kaynağa aynı anda yalnızca bir işaretçi sahip olabilir:

std::unique_ptr<Player> player = std::make_unique<Player>("Hero");
player->attack();  // Normal bir işaretçi gibi kullanın

// Sahipliği std::move ile aktarın
std::unique_ptr<Player> player2 = std::move(player);
// player artık nullptr'dir

shared_ptr

Paylaşımlı sahiplik - birden fazla işaretçi aynı kaynağa sahip olabilir. Bellek, son sahip yok edildiğinde serbest bırakılır:

std::shared_ptr<Player> p1 = std::make_shared<Player>("Hero");
std::shared_ptr<Player> p2 = p1;  // Her ikisi de kaynağa sahiptir

std::cout << p1.use_count();  // 2 yazdırır

weak_ptr

Bir shared_ptr'nin sahiplik içermeyen gözlemcisidir. Döngüsel referansları kırmak için kullanışlıdır:

std::shared_ptr<Player> shared = std::make_shared<Player>("Hero");
std::weak_ptr<Player> weak = shared;

if (auto locked = weak.lock()) {  // shared_ptr'ye dönüştür
    locked->attack();
}

En iyi uygulamalar: Tekil sahiplik için varsayılan olarak unique_ptr kullanın. Birden fazla nesnenin bir kaynağı paylaşması gerektiğinde shared_ptr kullanın. Yaşam süresini uzatmadan gözlemlemek için weak_ptr kullanın. Ham new yerine make_unique ve make_shared kullanmayı tercih edin.

Kendin dene

#include <iostream>
#include <memory>
#include <string>
#include "Document.h"

using namespace std;

int main() {
    string inputTitle;
    cin >> inputTitle;

    // TODO: inputTitle ile bir Document için unique_ptr oluşturun
    // std::make_unique kullanarak

    // TODO: "Unique owner: <title>" yazdırın

    // TODO: std::move kullanarak sahipliği başka bir unique_ptr nesnesine devredin

    // TODO: "Ownership transferred" yazdırın

    // TODO: "SharedDoc" başlıklı yeni bir Document için shared_ptr oluşturun
    // std::make_shared kullanarak

    // TODO: Aynı belgeyi işaret eden ikinci bir shared_ptr oluşturun

    // TODO: use_count() kullanarak "Shared owners: <count>" yazdırın

    // TODO: Paylaşılan işaretçilerden birinden bir weak_ptr oluşturun

    // TODO: weak_ptr üzerinden belgeye erişmek için lock() kullanın
    // ve "Weak access: <title>" yazdırın

    return 0;
}
quiz iconKendini test et

Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.

Nesne Yönelimli Programlama bölümündeki tüm dersler