Middle
Come funziona shared_ptr in C++?
sobes.tech AI
Risposta dell'AI
shared_ptr — è un puntatore intelligente che implementa la semantica di proprietà di una risorsa condivisa. Memorizza un puntatore all'oggetto e un puntatore al blocco di controllo.
Il blocco di controllo contiene:
- Contatore di riferimenti forti (reference count).
- Contatore di riferimenti deboli (weak count).
- Functor di eliminazione personalizzato (deleter), se specificato.
- Allocatore personalizzato, se specificato.
- Puntatore all'oggetto memorizzato (lo stesso di quello memorizzato in
shared_ptr).
Principio di funzionamento:
- Creazione: Quando si crea il primo
shared_ptrche punta a un oggetto, viene creato il blocco di controllo e i contatori di riferimenti vengono inizializzati: forti — 1, deboli — 0.std::shared_ptr<int> ptr1 = std::make_shared<int>(10); // Crea un oggetto int e un blocco di controllo - Copia: Quando si copia un
shared_ptr, il contatore di riferimenti forti nel blocco di controllo aumenta di 1.std::shared_ptr<int> ptr2 = ptr1; // Aumenta il contatore di riferimenti forti - Assegnazione: Quando si assegna un
shared_ptr, la risorsa vecchia viene decrementata (il contatore di riferimenti forti diminuisce), e la nuova risorsa viene incrementata (aumenta).std::shared_ptr<int> ptr3; ptr3 = ptr1; // Decrementa la vecchia risorsa di ptr3, Incrementa la risorsa di ptr1 - Distruzione: Quando un
shared_ptrviene distrutto (ad esempio, uscita dal scope), il contatore di riferimenti forti viene decrementato.{ std::shared_ptr<int> ptr4 = ptr1; // Aumenta il contatore di riferimenti forti // ptr4 esce dal scope } // Decrementa il contatore di riferimenti forti - Rilascio della risorsa: Quando il contatore di riferimenti forti raggiunge zero, la risorsa (l'oggetto puntato da
shared_ptr) viene eliminata usando il functor di eliminazione definito (odeletedi default). - Rilascio del blocco di controllo: Il blocco di controllo viene liberato quando entrambi i contatori (forti e deboli) raggiungono zero.
Vantaggi:
- Gestione automatica della memoria per risorse condivise.
- Sicurezza contro doppie liberazioni.
- Supporto per functor di eliminazione personalizzati.
Svantaggi:
- Le referenze cicliche possono portare a perdite di memoria (risolto con
weak_ptr). - Piccolo aumento dei costi a causa del blocco di controllo e delle operazioni atomiche sui contatori.
- Sicurezza nelle operazioni con lo stesso
shared_ptr(copia, assegnazione, modifica del puntatore memorizzato), ma non con l'oggetto a cui punta.