Sobes.tech
Middle

Miből áll egy shared_ptr?

sobes.tech MI

Válasz az MI-től

A shared_ptr két fő összetevőből áll:

  1. Az erőforrást kezelő mutató: Nyers mutató az objektumra, amelyet a shared_ptr kezel.

  2. A vezérlő blokk (Control Block) mutatója: Objektum, amely metaadatokat tartalmaz az kezelt erőforrásról. Ez a blokk dinamikusan allokálódik az első shared_ptr vagy weak_ptr létrehozásakor, amely az erőforrást mutatja.

A vezérlő blokk általában tartalmazza:

  • Erős hivatkozásszámláló (Strong Reference Count): A shared_ptr példányok száma, amelyek az erőforrásra mutatnak. Amikor ez a számláló eléri a nullát, az erőforrás törlődik.
  • Gyenge hivatkozásszámláló (Weak Reference Count): A weak_ptr példányok száma, amelyek az erőforrásra mutatnak. Az erőforrás csak akkor törlődik, amikor az erős hivatkozásszámláló eléri a nullát, függetlenül ettől a számlálótól. Azonban a vezérlő blokk csak akkor törlődik, amikor mindkét számláló nullára csökken.
  • A deleter (Deleter) információ: Opcionális felhasználói függvény vagy funktor az erőforrás törléséhez. Ha nincs megadva, akkor a delete kerül használatra.
  • Az allokátor (Allocator) információ: Opcionális allokátor az erőforrások és a vezérlő blokk allokálásához.

A shared_ptr és komponenseinek létrehozásának példája koncepcionális szinten:

// Tegyük fel, hogy van egy MyClass osztály
class MyClass {
public:
    MyClass() { std::cout << "MyClass létrehozva\n"; }
    ~MyClass() { std::cout << "MyClass megsemmisítve\n"; }
};

// shared_ptr létrehozása:
// MyClass objektum lefoglalása
// Vezérlő blokk lefoglalása
// A MyClass mutató beállítása a shared_ptr-ben
// A vezérlő blokk mutatójának beállítása a shared_ptr-ben
// A számlálók (erős = 1, gyenge = 0) inicializálása a vezérlő blokkban
std::shared_ptr<MyClass> ptr1 = std::make_shared<MyClass>();

// Másolás esetén:
// ptr2 ugyanarra az MyClass objektumra mutat
// ptr2 ugyanarra a vezérlő blokkra mutat
// Az erős hivatkozások számláló növelése a vezérlő blokkban (most 2)
std::shared_ptr<MyClass> ptr2 = ptr1;

// Egy shared_ptr törlésekor (pl. ptr1 kilép a hatókörből):
// Az erős hivatkozások számláló csökken (most 1)
// Az erőforrás NEM törlődik, mert a számláló > 0

// Az utolsó shared_ptr törlésekor (pl. ptr2 kilép a hatókörből):
// Az erős hivatkozások számláló csökken (most 0)
// A MyClass objektum törlődik
// A gyenge hivatkozások számláló csökken (itt 0)
// Mindkét számláló 0, a vezérlő blokk törlődik

Vizuális ábrázolás:

  • shared_ptr |-> [ Saját adatok (Erőforrás mutató, Vezérlő blokk mutatója) ]
    • [ Erőforrás mutató ] -> [ T típusú objektum ]
    • [ Vezérlő blokk mutatója ] -> [ Vezérlő blokk objektuma (Számlálók, Deleter, Allocator) ]