Sobes.tech
Middle

std::shared_ptr-də istinadçı sayğacı necə işləyir?

sobes.tech Süni İntellekt

AI-dan cavab

std::shared_ptr içindəki istinad sayğacı ayrıca bir obyektə - idarəetmə blokuna (control block) - yerləşdirilir.

Bu idarəetmə bloku aşağıdakı hallarda yaradılır:

  • Birinci dəfə std::shared_ptr göstəricisindən yaradıldıqda.
  • Özəl silici və ya ayırıcı ilə std::shared_ptr yaradıldıqda.
  • std::make_shared və ya std::allocate_shared istifadə olunduqda.

Bu idarəetmə bloku ən azı iki sayğacı ehtiva edir:

  1. Güclü istinad sayğacı (strong count): std::shared_ptr yaradıldıqda və ya kopyalandıqda artır. std::shared_ptr məhv edildikdə azaldılır. Bu sayğac sıfıra çatanda, idarə olunan obyekt sərbəst buraxılır.
  2. Zəif istinad sayğacı (weak count): std::shared_ptr-dən std::weak_ptr yaradıldıqda artır. std::weak_ptr məhv edildikdə azaldılır. Hər iki sayğac — güclü və zəif — sıfıra çatdıqda, idarəetmə bloku sərbəst buraxılır.

std::make_shared istifadəsi, birbaşa new ilə yaradılmadan üstün sayılır, çünki obyekt və idarəetmə bloku tək yaddaş blokunda yerləşdirilə bilər, bu da performansı yaxşılaşdırır və parçalanmanı azaldır.

Sayğaclar atomikdir, bu da std::shared_ptr-ın çox ipli mühitdə təhlükəsiz istifadəsini təmin edir, baxmayaraq ki, idarə olunan obyektə giriş standart olaraq sinxronlaşdırılmayıb.

Nümunə:

#include <iostream>
#include <memory>

struct MyObject {
    int data;
    MyObject(int d) : data(d) {
        std::cout << "MyObject(" << data << ") yaradıldı\n";
    }
    ~MyObject() {
        std::cout << "MyObject(" << data << ") məhv edildi\n";
    }
};

int main() {
    std::shared_ptr<MyObject> ptr1 = std::make_shared<MyObject>(10);
    // güclü sayğac: 1, zəif sayğac: 0

    {
        std::shared_ptr<MyObject> ptr2 = ptr1;
        // güclü sayğac: 2, zəif sayğac: 0

        std::weak_ptr<MyObject> weak_ptr = ptr1;
        // güclü sayğac: 2, zəif sayğac: 1

        if (auto locked_ptr = weak_ptr.lock()) {
            // güclü sayğac: 3, zəif sayğac: 1 (müvəqqəti lock daxilində)
            std::cout << "Obyekt məlumatı: " << locked_ptr->data << std::endl;
        }
        // güclü sayğac: 2, zəif sayğac: 1
    } // ptr2 scope-dan çıxır
    // güclü sayğac: 1, zəif sayğac: 1

    // Obyekt hələ də məhv edilməyib, çünki güclü sayğac == 1

    {
        std::weak_ptr<MyObject> weak_ptr2 = ptr1;
        // güclü sayğac: 1, zəif sayğac: 2
    } // weak_ptr2 scope-dan çıxır
    // güclü sayğac: 1, zəif sayğac: 1

} // ptr1 scope-dan çıxır
// güclü sayğac: 0, zəif sayğac: 1
// Obyekt məhv edilir, çünki güclü sayğac 0-a çatıb
// İdarəetmə bloku zəif sayğac 0 olana qədər qalır