Middle
Ako funguje shared_ptr v C++?
sobes.tech AI
Odpoveď od AI
shared_ptr — je inteligentný ukazovateľ, ktorý implementuje semantiku zdieľaného zdroja. Uchováva ukazovateľ na objekt a ukazovateľ na riadiacu blok.
Riadiaci blok obsahuje:
- Počítadlo silných odkazov (reference count).
- Počítadlo slabých odkazov (weak count).
- Používateľský funkcionár na vymazanie (deleter), ak je zadaný.
- Používateľský alokátor, ak je zadaný.
- Ukazovateľ na uložený objekt (to isté, čo je uložené v samotnom
shared_ptr).
Princíp práce:
- Vytvorenie: Pri vytvorení prvého
shared_ptr, ktorý ukazuje na objekt, sa vytvorí riadiaci blok, počítadlá odkazov sa inicializujú: silné — 1, slabé — 0.std::shared_ptr<int> ptr1 = std::make_shared<int>(10); // Vytvorí objekt int a riadiaci blok - Kopírovanie: Pri kopírovaní
shared_ptrsa počet silných odkazov v riadiacom bloku zvýši o 1.std::shared_ptr<int> ptr2 = ptr1; // Zvýši počet silných odkazov - Priradenie: Pri priradení
shared_ptrstarému zdroju sa decrement-uje (zníži) počet silných odkazov, novému zdroju sa increment-uje (zvýši).std::shared_ptr<int> ptr3; ptr3 = ptr1; // Decrement starého zdroja, Increment nového - Odstránenie: Pri zničení
shared_ptr(napríklad, pri ukončení platnosti) sa počet silných odkazov zníži.{ std::shared_ptr<int> ptr4 = ptr1; // Zvýši počet silných odkazov // ptr4 končí platnosť } // Zníži počet silných odkazov - Uvoľnenie zdroja: Keď počet silných odkazov dosiahne nulu, zdroj (objekt, na ktorý ukazuje
shared_ptr) sa odstráni pomocou zadaného funkcionára na vymazanie (alebodeleteako predvolené). - Uvoľnenie riadiaceho bloku: Riadiaci blok sa uvoľní, keď oba počítadlá (silné a slabé) dosiahnu nulu.
Výhody:
- Automatické riadenie pamäti pre zdieľané zdroje.
- Bezpečnosť pred dvojitým uvoľnením.
- Podpora používateľských funkcionárov na vymazanie.
Nevýhody:
- Cyklické odkazy môžu viesť k únikom pamäti (rieši sa pomocou
weak_ptr). - Mierne zvýšenie režijných nákladov kvôli riadiacemu bloku a atómovým operáciám s počítadlami.
- Vláknová bezpečnosť operácií s samým
shared_ptr(kopírovanie, priradenie, zmena uloženého ukazovateľa), ale nie s objektom, na ktorý ukazuje.