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_ptrjön létre ugyanarra az objektumra. Csökken, amikor ashared_ptrmegsemmisü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, amikorweak_ptrjön létreshared_ptr-ből. Csökken, amikor aweak_ptrmegsemmisü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.