Sobes.tech
Middle

Milyen alapon hivatkozhat több shared_ptr objektum ugyanarra a mutatóra?

sobes.tech MI

Válasz az MI-től

Néhány std::shared_ptr objektum ugyanarra a mutatóra hivatkozhat a vezérlő blokk (control block) megléte miatt.

A vezérlő blokk, amely a kezelendő objektumhoz kapcsolódik, tartalmazza:

  • Erős hivatkozási számláló (strong reference count): Növekszik, amikor új shared_ptr jön létre ugyanarra az objektumra. Csökken, amikor a shared_ptr megsemmisül. Amikor nullára csökken, az összekapcsolt objektum (mutató) törlődik.
  • Gyenge hivatkozási számláló (weak reference count): std::weak_ptr-hez használják. Növekszik, amikor weak_ptr jön létre shared_ptr-ből. Csökken, amikor a weak_ptr megsemmisül. Amikor mindkét számláló nullára csökken, a vezérlő blokk törlődik.
  • A kezelt objektum saját mutatója: Nem az adatmutató maga, hanem az, amit a blokk kezel.

Amikor shared_ptr-t hozunk létre egy meglévő shared_ptr-ből (másolás, másolás-értékadás), ugyanazt a vezérlő blokkot használják, és ebben a blokkban az erős hivatkozások száma növekszik.

Példa:

#include <memory>
#include <iostream>

struct MyData {
    int value;
    MyData(int v) : value(v) { std::cout << "MyData(" << value << ") created.\n"; }
    ~MyData() { std::cout << "MyData(" << value << ") destroyed.\n"; }
};

int main() {
    // Első shared_ptr létrehozása.
    // Vezérlő blokk és MyData objektum jön létre.
    // Erős számlálók: 1, gyenge: 0.
    std::shared_ptr<MyData> ptr1 = std::make_shared<MyData>(10);
    std::cout << "ptr1 use count: " << ptr1.use_count() << "\n";

    // Második shared_ptr létrehozása ptr1-ből.
    // Ugyanazt a vezérlő blokkot használják.
    // Az erős számláló 2-re nő.
    std::shared_ptr<MyData> ptr2 = ptr1;
    std::cout << "ptr1 use count: " << ptr1.use_count() << "\n";
    std::cout << "ptr2 use count: " << ptr2.use_count() << "\n";

    // Harmadik shared_ptr létrehozása ptr1-ből.
    // Ugyanazt a vezérlő blokkot használják.
    // Az erős számláló 3-ra nő.
    std::shared_ptr<MyData> ptr3 = ptr1;
     std::cout << "ptr1 use count: " << ptr1.use_count() << "\n";
    std::cout << "ptr2 use count: " << ptr2.use_count() << "\n";
    std::cout << "ptr3 use count: " << ptr3.use_count() << "\n";

    std::cout << "Scope elhagyása.\n";
    // ptr3 kilép a hatókörből.
    // Az erős számláló csökken 2-re.
    // ptr2 kilép a hatókörből.
    // Az erős számláló csökken 1-re.
    // ptr1 kilép a hatókörből.
    // Az erős számláló 0-ra csökken.
    // A MyData objektum megsemmisül.
    // A vezérlő blokk törlődik.
}

Minden shared_ptr objektumnak saját mutatója van a vezérlő blokkra és saját mutatója az adatobjektumra. Másoláskor mindkét mutató másolódik, és az erős hivatkozások száma a közös blokkban növekszik. Így minden shared_ptr ugyanarra a vezérlő blokkra mutat, amely nyomon követi a tulajdonos példányok számát és meghatározza az erőforrások felszabadításának pillanatát.