Middle
std::shared_ptr'da referans sayacı nasıl çalışır?
sobes.tech yapay zeka
AI'dan gelen yanıt
std::shared_ptr içindeki referans sayacı, ayrı bir nesnede saklanır: kontrol bloğunda (control block).
Kontrol bloğu şu durumlarda oluşturulur:
- Bir gösterge (pointer) kullanılarak ilk
std::shared_ptroluşturulduğunda. - Özelleştirilmiş bir silici veya ayırıcı ile
std::shared_ptroluşturulduğunda. std::make_sharedveyastd::allocate_sharedkullanıldığında.
Bu kontrol bloğu en az iki sayacı içerir:
- Güçlü referans sayacı (strong count): Bir
std::shared_ptroluşturulduğunda veya kopyalandığında artar. Birstd::shared_ptryok edildiğinde azalır. Bu sayaç sıfıra ulaşınca, yönetilen nesne serbest bırakılır. - Zayıf referans sayacı (weak count): Bir
std::weak_ptr, birstd::shared_ptr'dan oluşturulduğunda artar. Birstd::weak_ptryok edildiğinde azalır. Her iki sayaç da — güçlü ve zayıf — sıfıra ulaşınca, kontrol bloğu serbest bırakılır.
std::make_shared kullanımı, doğrudan new ile oluşturulmaya göre tercih edilir çünkü nesne ve kontrol bloğu tek bir bellek bloğunda tahsis edilebilir, bu da performansı artırır ve parçalanmayı azaltır.
Sayaçlar atomiktir, bu da std::shared_ptr'ın çok iş parçacıklı senaryolarda güvenli olmasını sağlar, ancak yönetilen nesneye erişim varsayılan olarak senkronize edilmemiştir.
Örnek:
#include <iostream>
#include <memory>
struct MyObject {
int data;
MyObject(int d) : data(d) {
std::cout << "MyObject(" << data << ") oluşturuldu\n";
}
~MyObject() {
std::cout << "MyObject(" << data << ") yok edildi\n";
}
};
int main() {
std::shared_ptr<MyObject> ptr1 = std::make_shared<MyObject>(10);
// güçlü sayaç: 1, zayıf sayaç: 0
{
std::shared_ptr<MyObject> ptr2 = ptr1;
// güçlü sayaç: 2, zayıf sayaç: 0
std::weak_ptr<MyObject> weak_ptr = ptr1;
// güçlü sayaç: 2, zayıf sayaç: 1
if (auto locked_ptr = weak_ptr.lock()) {
// güçlü sayaç: 3, zayıf sayaç: 1 (geçici lock içinde)
std::cout << "Nesne verisi: " << locked_ptr->data << std::endl;
}
// güçlü sayaç: 2, zayıf sayaç: 1
} // ptr2 kapsam dışına çıktı
// güçlü sayaç: 1, zayıf sayaç: 1
// Nesne henüz yok edilmedi, çünkü güçlü sayaç == 1
{
std::weak_ptr<MyObject> weak_ptr2 = ptr1;
// güçlü sayaç: 1, zayıf sayaç: 2
} // weak_ptr2 kapsam dışına çıktı
// güçlü sayaç: 1, zayıf sayaç: 1
} // ptr1 kapsam dışına çıktı
// güçlü sayaç: 0, zayıf sayaç: 1
// Nesne yok edildi, çünkü güçlü sayaç 0 oldu
// Kontrol bloğu, zayıf sayaç 0 olana kadar kalır