Pe ce bază pot mai multe obiecte shared_ptr face referire la același pointer?
sobes.tech AI
Răspuns de la AI
Mai multe obiecte std::shared_ptr pot referi la aceeași pointer datorită existenței unui bloc de control (control block).
Blocul de control asociat cu obiectul gestionat conține:
- Contorul de referințe puternice (strong reference count): Crește la crearea unui nou
shared_ptrpentru același obiect. Scade la distrugerea unuishared_ptr. Când ajunge la zero, obiectul asociat (pointerul) este șters. - Contorul de referințe slabe (weak reference count): Folosit pentru
std::weak_ptr. Crește la crearea unuiweak_ptrdintr-unshared_ptr. Scade la distrugerea unuiweak_ptr. Când ambii contori ajung la zero, blocul de control este șters. - Pointerul propriu către obiectul gestionat: Nu pointerul de date în sine, ci cel gestionat de bloc.
Când creezi un shared_ptr dintr-un alt shared_ptr existent (copiere, atribuție-copiere), amândoi încep să folosească același bloc de control, iar contorul de referințe puternice din acest bloc crește.
Exemplu:
#include <memory>
#include <iostream>
struct MyData {
int value;
MyData(int v) : value(v) { std::cout << "MyData(" << value << ") creat.\n"; }
~MyData() { std::cout << "MyData(" << value << ") distrus.\n"; }
};
int main() {
// Se creează primul shared_ptr.
// Se creează blocul de control și obiectul MyData.
// Contorii: puternic: 1, slab: 0.
std::shared_ptr<MyData> ptr1 = std::make_shared<MyData>(10);
std::cout << "numărul de utilizare ptr1: " << ptr1.use_count() << "\n";
// Se creează al doilea shared_ptr din ptr1.
// Se folosește același bloc de control.
// Contorul puternic crește la 2.
std::shared_ptr<MyData> ptr2 = ptr1;
std::cout << "numărul de utilizare ptr1: " << ptr1.use_count() << "\n";
std::cout << "numărul de utilizare ptr2: " << ptr2.use_count() << "\n";
// Se creează al treilea shared_ptr din ptr1.
// Se folosește același bloc de control.
// Contorul puternic crește la 3.
std::shared_ptr<MyData> ptr3 = ptr1;
std::cout << "numărul de utilizare ptr1: " << ptr1.use_count() << "\n";
std::cout << "numărul de utilizare ptr2: " << ptr2.use_count() << "\n";
std::cout << "numărul de utilizare ptr3: " << ptr3.use_count() << "\n";
std::cout << "Ieșire din scop.\n";
// ptr3 iese din scop.
// Contorul puternic scade la 2.
// ptr2 iese din scop.
// Contorul puternic scade la 1.
// ptr1 iese din scop.
// Contorul puternic scade la 0.
// Obiectul MyData este distrus.
// Blocul de control este șters.
}
Fiecare obiect shared_ptr conține propriul pointer către blocul de control și propriul pointer către obiectul de date. La copierea unui shared_ptr, se copiază ambii pointeri, iar contorul de referințe puternice din blocul comun crește. Astfel, toate shared_ptr indică către același bloc de control, care urmărește numărul de copii deținători și determină momentul distrugerii resursei gestionate.