Middle
Millisel alusel võivad mitu shared_ptr objekti viidata samale näidisele?
sobes.tech AI
Vastus AI-lt
Mõned std::shared_ptr objektid võivad viidata samale näidisele tänu kontrollibloki (control block) olemasolule.
Kontrolliblokk, mis on seotud hallatava objektiga, sisaldab:
- Tugevate viidete loendur (strong reference count): Kasvab, kui luuakse uus
shared_ptrsama objekti jaoks. Väheneb, kuishared_ptrhävib. Kui see jõuab nulli, eemaldatakse seotud objekt (näidik). - Nõrkade viidete loendur (weak reference count): Kasutatakse
std::weak_ptrjaoks. Kasvab, kuiweak_ptrluuakseshared_ptr-st. Väheneb, kuiweak_ptrhävib. Kui mõlemad loendurid jõuavad nulli, eemaldatakse kontrolliblokk. - Oma näidik hallatava objekti kohta: Mitte andmete näidik, vaid see, mida kontrolliblokk haldab.
Kui loote shared_ptr olemasolevast shared_ptr-st (kopeerimine, omistamine kopeerimisega), hakkavad nad kasutama sama kontrolliblokki ning tugeva viidete loendur selles blokis suureneb.
Näide:
#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() {
// Esimese `shared_ptr` loomine:
// Loob kontrollibloki ja MyData objekti:
// tugevad loendurid: 1, nõrgad: 0.
std::shared_ptr<MyData> ptr1 = std::make_shared<MyData>(10);
std::cout << "ptr1 use count: " << ptr1.use_count() << "\n";
// Teise `shared_ptr` loomine ptr1-st:
// Kasutatakse sama kontrollibloki:
// tugevate loendur tõuseb 2-le.
std::shared_ptr<MyData> ptr2 = ptr1;
std::cout << "ptr1 use count: " << ptr1.use_count() << "\n";
std::cout << "ptr2 use count: " << ptr2.use_count() << "\n";
// Kolmanda `shared_ptr` loomine ptr1-st:
// Kasutatakse sama kontrollibloki:
// tugevate loendur tõuseb 3-le.
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 << "Väljumine ulatusest.\n";
// ptr3 väljub ulatusest:
// tugevate loendurite arv väheneb 2-le.
// ptr2 väljub ulatusest:
// tugevate loendurite arv väheneb 1-le.
// ptr1 väljub ulatusest:
// tugevate loendurite arv väheneb 0-le.
// MyData objekt hävib.
// Kontrolliblokk eemaldatakse.
}
Iga shared_ptr objekt sisaldab oma viidet kontrolliblokile ja oma viidet andmete objektile. Kopeerimisel kopeeritakse mõlemad viited ning selle ühise bloki tugevate viidete arv suureneb. Nii viitavad kõik shared_ptr-d samale kontrolliblokile, mis jälgib nende koopiate arvu ning määrab hallatava ressursi vabastamise hetke.