Op welke basis kunnen meerdere shared_ptr-objecten naar dezelfde pointer verwijzen?
sobes.tech AI
Antwoord van AI
Meerdere objecten std::shared_ptr kunnen naar dezelfde pointer verwijzen dankzij de aanwezigheid van een controleblok (control block).
Het controleblok dat gekoppeld is aan het beheerde object bevat:
- Sterke referentieteller (strong reference count): Verhoogt bij het maken van een nieuwe
shared_ptrvoor hetzelfde object. Verlaagt bij het vernietigen van eenshared_ptr. Wanneer deze nul wordt, wordt het bijbehorende object (pointer) verwijderd. - Zwakke referentieteller (weak reference count): Gebruikt voor
std::weak_ptr. Verhoogt bij het maken van eenweak_ptruit eenshared_ptr. Verlaagt bij het vernietigen van eenweak_ptr. Wanneer beide tellers nul worden, wordt het controleblok verwijderd. - Eigen pointer naar het beheerde object: Niet de data pointer zelf, maar degene die door het controleblok wordt beheerd.
Wanneer je een shared_ptr maakt uit een bestaande shared_ptr (kopiëren, toewijzing-kopiëren), beginnen ze hetzelfde controleblok te gebruiken, en wordt de sterke referentieteller in dat blok verhoogd.
Voorbeeld:
#include <memory>
#include <iostream>
struct MyData {
int value;
MyData(int v) : value(v) { std::cout << "MyData(" << value << ") gemaakt.\n"; }
~MyData() { std::cout << "MyData(" << value << ") verwijderd.\n"; }
};
int main() {
// Eerste shared_ptr wordt gemaakt.
// Controleblok en MyData-object worden gemaakt.
// Tellers: sterk: 1, zwak: 0.
std::shared_ptr<MyData> ptr1 = std::make_shared<MyData>(10);
std::cout << "gebruik tellen van ptr1: " << ptr1.use_count() << "\n";
// Tweede shared_ptr wordt uit ptr1 gemaakt.
// Gebruikt hetzelfde controleblok.
// De sterke teller wordt verhoogd naar 2.
std::shared_ptr<MyData> ptr2 = ptr1;
std::cout << "gebruik tellen van ptr1: " << ptr1.use_count() << "\n";
std::cout << "gebruik tellen van ptr2: " << ptr2.use_count() << "\n";
// Derde shared_ptr wordt uit ptr1 gemaakt.
// Gebruikt hetzelfde controleblok.
// De sterke teller wordt verhoogd naar 3.
std::shared_ptr<MyData> ptr3 = ptr1;
std::cout << "gebruik tellen van ptr1: " << ptr1.use_count() << "\n";
std::cout << "gebruik tellen van ptr2: " << ptr2.use_count() << "\n";
std::cout << "gebruik tellen van ptr3: " << ptr3.use_count() << "\n";
std::cout << "Scope verlaten.\n";
// ptr3 verlaat scope.
// De sterke teller daalt naar 2.
// ptr2 verlaat scope.
// De sterke teller daalt naar 1.
// ptr1 verlaat scope.
// De sterke teller daalt naar 0.
// Het MyData-object wordt verwijderd.
// Het controleblok wordt verwijderd.
}
Elk shared_ptr object bevat zijn eigen pointer naar het controleblok en zijn eigen pointer naar het gegevensobject. Bij kopiëren van een shared_ptr worden beide pointers gekopieerd, en wordt de sterke referentieteller in het gemeenschappelijke controleblok verhoogd. Op deze manier wijzen alle shared_ptr naar hetzelfde controleblok, dat het aantal bezittingen bijhoudt en het moment van vernietiging van de beheerde hulpbron bepaalt.