Middle
Na základě čeho mohou více objektů shared_ptr odkazovat na stejný ukazatel?
sobes.tech AI
Odpověď od AI
Několik objektů std::shared_ptr může odkazovat na stejný ukazatel díky přítomnosti řídicího bloku (control block).
Řídicí blok, který je spojen s řízeným objektem, obsahuje:
- Počítadlo silných odkazů (strong reference count): Zvyšuje se při vytváření nového
shared_ptrpro stejný objekt. Snižuje se při zánikushared_ptr. Když dosáhne nuly, odkazovaný objekt (ukazatel) je odstraněn. - Počítadlo slabých odkazů (weak reference count): Používá se pro
std::weak_ptr. Zvyšuje se při vytvářeníweak_ptrzshared_ptr. Snižuje se při zánikuweak_ptr. Když jsou oba počítadla nulová, řídicí blok je odstraněn. - Vlastní ukazatel na řízený objekt: Ne samotný datový ukazatel, ale ten, který je řízen blokem.
Když vytvoříte shared_ptr z existujícího shared_ptr (kopírování, přiřazení kopírováním), začnou používat stejný řídicí blok a počet silných odkazů v tomto bloku se zvýší.
Příklad:
#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() {
// Vytvoření prvního shared_ptr.
// Vytvoří se řídicí blok a objekt MyData.
// Počítadla strong: 1, weak: 0.
std::shared_ptr<MyData> ptr1 = std::make_shared<MyData>(10);
std::cout << "ptr1 use count: " << ptr1.use_count() << "\n";
// Vytvoření druhého shared_ptr z ptr1.
// Používá stejný řídicí blok.
// Počítadlo strong se zvýší na 2.
std::shared_ptr<MyData> ptr2 = ptr1;
std::cout << "ptr1 use count: " << ptr1.use_count() << "\n";
std::cout << "ptr2 use count: " << ptr2.use_count() << "\n";
// Vytvoření třetího shared_ptr z ptr1.
// Používá stejný řídicí blok.
// Počítadlo strong se zvýší na 3.
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 << "Opouštění rozsahu.\n";
// ptr3 opouští rozsah.
// Počítadlo strong klesne na 2.
// ptr2 opouští rozsah.
// Počítadlo strong klesne na 1.
// ptr1 opouští rozsah.
// Počítadlo strong klesne na 0.
// Objekt MyData je zničen.
// Řídicí blok je odstraněn.
}
Každý objekt shared_ptr obsahuje svůj ukazatel na řídicí blok a svůj ukazatel na datový objekt. Při kopírování shared_ptr jsou kopírovány oba tyto ukazatele a počet silných odkazů v sdíleném řídicím bloku se zvyšuje. Tímto způsobem všechny shared_ptr odkazují na stejný řídicí blok, který sleduje počet vlastněných kopií a určuje okamžik uvolnění řízeného zdroje.