Middle
Kādas pamata dēļ vairāki shared_ptr objekti var atsaukties uz to pašu norādītāju?
sobes.tech AI
Atbilde no AI
Dažas std::shared_ptr objekti varētu atsaukties uz to pašu norādi, pateicoties kontroles blokam (control block).
Kontroles bloks, kas ir saistīts ar pārvaldāmo objektu, satur:
- Stipro atsauces skaitītāju (strong reference count): Palielinās, kad tiek izveidots jauns
shared_ptrtam pašam objektam. Samazinās, kadshared_ptrtiek iznīcināts. Kad tas sasniedz nulli, saistītais objekts (norāde) tiek dzēsts. - Vāju atsauces skaitītāju (weak reference count): Pielietojams
std::weak_ptr. Palielinās, kadweak_ptrtiek izveidots noshared_ptr. Samazinās, kadweak_ptrtiek iznīcināts. Kad abi skaitītāji ir nulle, kontrolējošais bloks tiek dzēsts. - Paša pārvaldāmā objekta norāde: Ne dati, bet norāde, ko pārvalda bloks.
Kad jūs izveidojat shared_ptr no esoša shared_ptr (kopēšana, piešķiršana ar kopēšanu), tie sāk izmantot to pašu kontrolējošo bloku, un stipro atsauces skaitītājs šajā blokā palielinās.
Piemērs:
#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() {
// Pirmā `shared_ptr` izveide:
// Tiek izveidots kontrolējošais bloks un objekts MyData:
// stiprais skaitītājs: 1, vājais: 0.
std::shared_ptr<MyData> ptr1 = std::make_shared<MyData>(10);
std::cout << "ptr1 use count: " << ptr1.use_count() << "\n";
// Otrs `shared_ptr` no ptr1:
// Izmanto to pašu kontrolējošo bloku:
// stiprais skaitītājs palielinās līdz 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";
// Trešais `shared_ptr` no ptr1:
// Izmanto to pašu kontrolējošo bloku:
// stiprais skaitītājs palielinās līdz 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 << "Iziet no apgabala.\n";
// ptr3 iziet no apgabala:
// stiprais skaitītājs samazinās līdz 2.
// ptr2 iziet no apgabala:
// stiprais skaitītājs samazinās līdz 1.
// ptr1 iziet no apgabala:
// stiprais skaitītājs samazinās līdz 0.
// Objekts MyData tiek dzēsts.
// Kontrolējošais bloks tiek izdzēsts.
}
Katrs shared_ptr objekts satur savu norādi uz kontrolējošo bloku un savu norādi uz datu objektu. Kopējot shared_ptr, tiek kopēti abi norādītāji, un stipro atsauces skaitītājs kopīgajā blokā palielinās. Tādējādi visi shared_ptr norāda uz to pašu kontrolējošo bloku, kas uzrauga to kopiju skaitu un nosaka brīža, kad jāatbrīvo pārvaldītais resurss.