Sobes.tech
Middle

Hogyan működik a shared_ptr C++-ban?

sobes.tech MI

Válasz az MI-től

shared_ptr — ez egy okos mutató, amely megvalósítja a megosztott erőforrás tulajdonjogának szemantikáját. Tárol egy mutatót az objektumra és egy mutatót a vezérlő blokkra.

A vezérlő blokk tartalmazza:

  • Erős hivatkozási számláló (reference count).
  • Gyenge hivatkozási számláló (weak count).
  • Felhasználó által definiált törlőfüggvény (deleter), ha meg van adva.
  • Felhasználó által definiált allokátor, ha meg van adva.
  • Mutató a tárolt objektumra (ugyanaz, mint a shared_ptr-ben).

Működési elv:

  1. Létrehozás: Az első shared_ptr létrehozásakor, amely egy objektumra mutat, létrejön a vezérlő blokk, és a számlálók inicializálódnak: erős — 1, gyenge — 0.
    std::shared_ptr<int> ptr1 = std::make_shared<int>(10); // Létrehoz egy int objektumot és egy vezérlő blokkot
    
  2. Másolás: A shared_ptr másolásakor a vezérlő blokkban az erős hivatkozási számláló növekszik 1-gyel.
    std::shared_ptr<int> ptr2 = ptr1; // Növeli az erős hivatkozási számlálót
    
  3. Hozzárendelés: A shared_ptr hozzárendelésekor a régi erőforrás csökken (az erős számláló csökken), az új erőforrás növekszik (növekszik).
    std::shared_ptr<int> ptr3;
    ptr3 = ptr1; // Csökkenti a ptr3 régi erőforrását, növeli a ptr1 erőforrását
    
  4. Törlés: A shared_ptr megsemmisítésekor (pl. scope-ból való kilépéskor) az erős hivatkozási számláló csökken.
    {
        std::shared_ptr<int> ptr4 = ptr1; // Növeli az erős hivatkozási számlálót
        // ptr4 kilép a scope-ból
    } // Csökkenti az erős hivatkozási számlálót
    
  5. Erőforrás felszabadítása: Amikor az erős hivatkozási számláló eléri a nullát, az erőforrás (az objektum, amelyre a shared_ptr mutat) törlődik a megadott törlőfüggvény segítségével (vagy alapértelmezett delete-el).
  6. A vezérlő blokk felszabadítása: A vezérlő blokk akkor szabadul fel, amikor mindkét számláló (erős és gyenge) nullára csökken.

Előnyök:

  • Automatikus memória kezelés a megosztott erőforrásokhoz.
  • Biztonság a duplikált felszabadítás ellen.
  • Támogatás a felhasználó által definiált törlőfüggvényekhez.

Hátrányok:

  • A ciklikus hivatkozások memória szivárgáshoz vezethetnek (weak_ptr segítségével oldható meg).
  • Kis többletköltség a vezérlő blokk és az atomikus műveletek miatt a számlálók felett.
  • Biztonság a saját shared_ptr műveleteiben (másolás, hozzárendelés, mutató módosítása), de nem a objektum esetében, amelyhez mutat.