Ce face std::shared_ptr
std::shared_ptr permite mai multor pointeri să dețină același obiect. Intern ține un contor de referințe: fiecare copie îl crește, fiecare copie distrusă îl scade, iar când ajunge la 0 obiectul este șters.
p.use_count() returnează câți shared_ptr dețin obiectul în acest moment. Este util pentru a înțelege mecanismul, dar nu te baza pe el în logica programului când lucrezi cu fire de execuție.
Folosește-l doar când proprietatea este cu adevărat împărțită. Dacă un singur loc deține obiectul, std::unique_ptr este mai simplu și mai rapid.
Ce returnează
Un obiect care deține (în comun) pointerul. use_count() returnează numărul de proprietari (long).
Exemple
Exemplul 1: Contorul de referințe
Copia din blocul interior crește contorul la 2; la ieșirea din bloc scade înapoi la 1.
#include <memory>
#include <print>
#include <string>
int main() {
auto oras = std::make_shared<std::string>("Iași");
std::println("proprietari: {}", oras.use_count());
{
std::shared_ptr<std::string> copie = oras;
std::println("proprietari: {} ({})", oras.use_count(), *copie);
}
std::println("proprietari: {}", oras.use_count());
}
Rezultat
proprietari: 1
proprietari: 2 (Iași)
proprietari: 1
Exemplul 2: Un obiect folosit de mai mulți
Două conturi folosesc aceeași configurație. Obiectul este șters abia când dispare și ultimul cont.
#include <memory>
#include <print>
#include <string>
struct Config {
std::string moneda = "lei";
~Config() { std::println("Config șters"); }
};
struct Cont {
std::string titular;
std::shared_ptr<Config> cfg;
};
int main() {
auto cfg = std::make_shared<Config>();
Cont a{"Ana", cfg};
Cont b{"Mihai", cfg};
cfg.reset(); // main nu mai deține configurația, conturile da
std::println("{} folosește {}, proprietari: {}", a.titular, a.cfg->moneda, a.cfg.use_count());
std::println("{} folosește {}", b.titular, b.cfg->moneda);
}
Rezultat
Ana folosește lei, proprietari: 2
Mihai folosește lei
Config șters
Greșeli frecvente
- Doi
shared_ptrcare se țin unul pe altul (de exemplu părinte și copil) formează un ciclu: contorul nu ajunge niciodată la 0 și obiectele nu sunt șterse. Rupe ciclul custd::weak_ptr. - Creezi doi
shared_ptrseparați din același pointer brut (std::shared_ptr<T> a(p), b(p);). Fiecare are contorul lui și obiectul va fi șters de două ori.
Comenzi înrudite
std::make_shared: Creează un obiect și un std::shared_ptr care îl deține, cu o singură alocare de memorie.std::weak_ptr: Referință slabă la un obiect deținut de shared_ptr: nu îl ține în viață; lock() îl folosește în siguranță.std::unique_ptr: Pointer inteligent care deține singur un obiect și îl șterge automat când iese din domeniu.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.