Ce face std::weak_ptr
std::weak_ptr „observă” un obiect deținut de unul sau mai mulți std::shared_ptr, fără să crească contorul. Obiectul poate fi șters oricând de proprietarii lui.
Ca să folosești obiectul, apelezi w.lock(): dacă obiectul încă există, primești un shared_ptr valid (care îl ține în viață cât timp îl folosești); dacă nu, primești un shared_ptr gol. w.expired() spune doar dacă obiectul a dispărut.
Principala utilizare: ruperea ciclurilor dintre shared_ptr (copilul ține un weak_ptr spre părinte) și cache-uri care nu trebuie să țină obiectele în viață.
Ce returnează
lock() returnează un std::shared_ptr<T>, gol dacă obiectul a fost șters.
Exemple
Exemplul 1: lock() înainte și după ștergere
#include <memory>
#include <print>
#include <string>
void foloseste(const std::weak_ptr<std::string>& w) {
if (auto p = w.lock()) {
std::println("Obiectul există: {}", *p);
} else {
std::println("Obiectul a fost șters");
}
}
int main() {
auto utilizator = std::make_shared<std::string>("Ana");
std::weak_ptr<std::string> w = utilizator;
std::println("proprietari: {}", utilizator.use_count()); // weak_ptr nu contează
foloseste(w);
utilizator.reset();
foloseste(w);
std::println("expired: {}", w.expired());
}
Rezultat
proprietari: 1
Obiectul există: Ana
Obiectul a fost șters
expired: true
Exemplul 2: Ruperea unui ciclu părinte–copil
Părintele deține copilul prin shared_ptr, copilul vede părintele prin weak_ptr. Ambele obiecte sunt șterse la final.
#include <memory>
#include <print>
#include <string>
struct Parinte;
struct Copil {
std::weak_ptr<Parinte> parinte;
~Copil() { std::println("Copil șters"); }
};
struct Parinte {
std::string nume = "Maria";
std::shared_ptr<Copil> copil;
~Parinte() { std::println("Părinte șters"); }
};
int main() {
auto p = std::make_shared<Parinte>();
p->copil = std::make_shared<Copil>();
p->copil->parinte = p;
if (auto par = p->copil->parinte.lock()) {
std::println("Părintele copilului: {}", par->nume);
}
}
Rezultat
Părintele copilului: Maria
Părinte șters
Copil șters
Greșeli frecvente
- Verifici
!w.expired()și apoi folosești obiectul. Între cele două momente obiectul poate dispărea (mai ales cu fire de execuție). Folosește mereulock()și verifică rezultatul.
Comenzi înrudite
std::shared_ptr: Pointer inteligent cu proprietate comună: obiectul este șters când ultimul shared_ptr dispare.std::make_shared: Creează un obiect și un std::shared_ptr care îl deține, cu o singură alocare de memorie.std::enable_shared_from_this: Clasă de bază care permite unui obiect deținut de shared_ptr să obțină un shared_ptr către el însuși.