Modulelessen (2/2)
std::zwakke_ptr
Hoewel std::shared_ptr uiterst nuttig is, kan het uitsluitend vertrouwen op gedeeld eigendom leiden tot een probleem dat bekend staat als een circulaire referentie (of cyclische afhankelijkheid).
Als twee of meer objecten elk een shared_ptr bevatten die naar de ander wijst, ontstaat er een gesloten lus. In deze situatie zal de referentietelling van geen van beide objecten ooit nul bereiken, waardoor de toewijzing wordt voorkomen en een geheugenlek ontstaat.
Wat is std::weak_ptr
Om eigendomscycli te doorbreken, biedt de standaardbibliotheek std::weak_ptr. Dit is een slimme aanwijzer die een object observeert dat wordt beheerd door een shared_ptr, maar zonder het aantal referenties te verhogen.
Het is niet rechtstreeks eigenaar van de hulpbron en voorkomt dus niet de vernietiging ervan.
#include <memory>
std::shared_ptr<int> shared = std::make_shared<int>(42);
std::weak_ptr<int> weak = shared; // Does not increment reference count!De bron verifiëren en openen
Omdat een weak_ptr niet de eigenaar van de bron is, kan de toewijzing van de bron op elk moment ongedaan worden gemaakt (wanneer alle gekoppelde shared_ptr instanties buiten het bereik vallen).
Om de waargenomen bron te gebruiken, moeten we:
- Controleer of het nog geldig is met
expired(). - Converteer de
weak_ptrtijdelijk naar eenshared_ptrmet behulp van delock()methode. Als de bron nog steeds actief is, retourneertlock()een geldigeshared_ptr, anders retourneert het een nulaanwijzer (nullptr).
if (!weak.expired()) {
// lock() creates a temporary shared_ptr to ensure safe access
if (std::shared_ptr<int> sharedAccess = weak.lock()) {
std::cout << *sharedAccess << std::endl;
}
} else {
std::cout << "Resource deallocated!" << std::endl;
}Probeer het zelf
Declareer een std::weak_ptr<int> met de naam wPtr geïnitialiseerd vanuit sPtr. Druk vervolgens het Booleaanse resultaat af dat wordt geretourneerd door wPtr.expired() met behulp van std::cout.
Toon hint
Declareer de `weak_ptr` die hetzelfde generieke type `<int>` aangeeft en wijs `sPtr` er direct aan toe.
Oplossing beschikbaar na 3 pogingen
Gebruik de lock()-methode op wPtr om een tijdelijke shared_ptr te verkrijgen. Als de bewerking slaagt (de aanwijzer is niet nul), drukt u de gederefereerde waarde af.
Toon hint
Initialiseer een variabele binnen een `if`-blok door `wPtr.lock()` aan te roepen en druk vervolgens de bron af, waarbij u de verwijzingen verwijdert met de asterisk `*`.
Oplossing beschikbaar na 3 pogingen