C ++ 03
std::auto_ptr
- Forse uno degli originali soffriva della sindrome della prima stesura fornendo solo strutture limitate per la raccolta dei rifiuti. Il primo svantaggio è che richiede delete
la distruzione rendendoli inaccettabili per contenere oggetti allocati da array ( new[]
). Prende la proprietà del puntatore, quindi due puntatori automatici non dovrebbero contenere lo stesso oggetto. L'assegnazione trasferirà la proprietà e reimposterà il puntatore automatico rvalue su un puntatore nullo. Il che porta forse al peggior inconveniente; non possono essere utilizzati all'interno di contenitori STL a causa della suddetta impossibilità di essere copiati. Il colpo finale a qualsiasi caso d'uso è che dovrebbero essere deprecati nel prossimo standard di C ++.
std::auto_ptr_ref
- Questo non è un puntatore intelligente, in realtà è un dettaglio di progettazione utilizzato insieme a std::auto_ptr
per consentire la copia e l'assegnazione in determinate situazioni. In particolare, può essere utilizzato per convertire un non-const std::auto_ptr
in un lvalue utilizzando il trucco di Colvin-Gibbons noto anche come costruttore di mosse per trasferire la proprietà.
Al contrario, forse std::auto_ptr
non è stato concepito per essere utilizzato come puntatore intelligente generico per la raccolta automatica dei rifiuti. La maggior parte della mia comprensione e delle mie supposizioni limitate si basa sull'uso efficace di auto_ptr di Herb Sutter e lo uso regolarmente anche se non sempre nel modo più ottimizzato.
C ++ 11
std::unique_ptr
- Questo è il nostro amico che lo sostituirà std::auto_ptr
sarà abbastanza simile tranne che con i miglioramenti chiave per correggere i punti deboli std::auto_ptr
come lavorare con gli array, protezione lvalue tramite il costruttore di copie private, essere utilizzabile con contenitori STL e algoritmi, ecc. Poiché è un sovraccarico delle prestazioni e l'impronta di memoria è limitata, questo è un candidato ideale per sostituire, o forse più appropriatamente descritto come proprietario di puntatori grezzi. Come "unico" implica che esiste un solo proprietario del puntatore proprio come il precedente std::auto_ptr
.
std::shared_ptr
- Credo che sia basato su TR1 e boost::shared_ptr
ma migliorato per includere anche l'aliasing e l'aritmetica dei puntatori. In breve, avvolge un puntatore intelligente con conteggio di riferimento attorno a un oggetto allocato dinamicamente. Poiché "condiviso" implica che il puntatore può essere di proprietà di più di un puntatore condiviso quando l'ultimo riferimento dell'ultimo puntatore condiviso esce dall'ambito, l'oggetto verrà eliminato in modo appropriato. Questi sono anche thread-safe e nella maggior parte dei casi possono gestire tipi incompleti. std::make_shared
può essere utilizzato per costruire in modo efficiente std::shared_ptr
un'allocazione con uno heap utilizzando l'allocatore predefinito.
std::weak_ptr
- Allo stesso modo basato su TR1 e boost::weak_ptr
. Questo è un riferimento a un oggetto di proprietà di a std::shared_ptr
e quindi non impedirà l'eliminazione dell'oggetto se il std::shared_ptr
conteggio dei riferimenti scende a zero. Per avere accesso al puntatore grezzo devi prima accedere std::shared_ptr
a chiamando lock
che restituirà un vuoto std::shared_ptr
se il puntatore di proprietà è scaduto ed è già stato distrutto. Ciò è principalmente utile per evitare conteggi di riferimenti sospesi indefiniti quando si utilizzano più puntatori intelligenti.
Incremento
boost::shared_ptr
- Probabilmente il più facile da usare negli scenari più diversi (STL, PIMPL, RAII, ecc.) Questo è un puntatore intelligente conteggio referenziato condiviso. Ho sentito alcune lamentele sulle prestazioni e le spese generali in alcune situazioni, ma devo averle ignorate perché non ricordo quale fosse l'argomento. Apparentemente era abbastanza popolare da diventare un oggetto C ++ standard in sospeso e non vengono in mente svantaggi rispetto alla norma per quanto riguarda i puntatori intelligenti.
boost::weak_ptr
- In modo molto simile alla descrizione precedente di std::weak_ptr
, basata su questa implementazione, ciò consente un riferimento non proprietario a un file boost::shared_ptr
. Non sorprende che tu chiami lock()
per accedere al puntatore condiviso "forte" e devi controllare che sia valido in quanto potrebbe essere già stato distrutto. Assicurati solo di non memorizzare il puntatore condiviso restituito e lascia che esca dall'ambito non appena hai finito, altrimenti torni subito al problema del riferimento ciclico in cui i conteggi dei riferimenti si bloccheranno e gli oggetti non verranno distrutti.
boost::scoped_ptr
- Questa è una semplice classe di puntatori intelligenti con un piccolo overhead probabilmente progettata per un'alternativa più performante a boost::shared_ptr
quando utilizzabile. È paragonabile std::auto_ptr
soprattutto al fatto che non può essere utilizzato in modo sicuro come elemento di un contenitore STL o con più puntatori allo stesso oggetto.
boost::intrusive_ptr
- Non l'ho mai usato, ma dalla mia comprensione è progettato per essere utilizzato durante la creazione di classi compatibili con il puntatore intelligente. Devi implementare tu stesso il conteggio dei riferimenti, dovrai anche implementare alcuni metodi se vuoi che la tua classe sia generica, inoltre dovresti implementare la tua thread safety. Tra i lati positivi, questo probabilmente ti offre il modo più personalizzato di scegliere e scegliere esattamente quanto o quanto poca "intelligenza" desideri. intrusive_ptr
è in genere più efficiente di shared_ptr
quanto ti consente di avere una singola allocazione di heap per oggetto. (grazie Arvid)
boost::shared_array
- Questo è un boost::shared_ptr
array per. Fondamentalmente new []
, operator[]
e ovviamente delete []
sono al forno. Questo può essere usato nei contenitori STL e per quanto ne so fa tutto boost:shared_ptr
, anche se non puoi usarli boost::weak_ptr
con questi. È tuttavia possibile utilizzare in alternativa un boost::shared_ptr<std::vector<>>
per funzionalità simili e per riacquistare la capacità di utilizzare boost::weak_ptr
per i riferimenti.
boost::scoped_array
- Questo è un boost::scoped_ptr
array per. Come con boost::shared_array
tutta la bontà dell'array necessaria è incorporata. Questo non è copiabili e quindi non può essere utilizzato nei contenitori STL. Ho trovato quasi ovunque ti ritrovi a voler usare questo che probabilmente potresti semplicemente usare std::vector
. Non ho mai determinato quale sia effettivamente più veloce o abbia meno overhead, ma questo array con scope sembra molto meno coinvolto di un vettore STL. Quando vuoi mantenere l'allocazione sullo stack, considera boost::array
invece.
Qt
QPointer
- Introdotto in Qt 4.0, questo è un puntatore intelligente "debole" che funziona solo con QObject
classi derivate e che nel framework Qt è quasi tutto, quindi non è davvero una limitazione. Tuttavia ci sono limitazioni, vale a dire che non fornisce un puntatore "forte" e sebbene tu possa controllare se l'oggetto sottostante è valido, isNull()
potresti scoprire che il tuo oggetto viene distrutto subito dopo aver superato quel controllo, specialmente in ambienti multi-thread. Le persone Qt lo considerano deprecato, credo.
QSharedDataPointer
- Questo è un puntatore intelligente "forte" potenzialmente paragonabile a boost::intrusive_ptr
sebbene abbia alcuni thread safety incorporati, ma richiede di includere metodi di conteggio dei riferimenti ( ref
e deref
) che puoi fare sottoclasse QSharedData
. Come con gran parte di Qt, gli oggetti vengono utilizzati al meglio attraverso un'ampia eredità e sottoclasse tutto sembra essere il design previsto.
QExplicitlySharedDataPointer
- Molto simile a QSharedDataPointer
tranne che non chiama implicitamente detach()
. Chiamerei questa versione 2.0 in QSharedDataPointer
quanto quel leggero aumento del controllo su esattamente quando staccare dopo che il conteggio dei riferimenti è sceso a zero non vale particolarmente un oggetto completamente nuovo.
QSharedPointer
- Conteggio dei riferimenti atomici, thread safe, puntatore condivisibile, eliminazioni personalizzate (supporto array), sembra tutto ciò che dovrebbe essere un puntatore intelligente. Questo è ciò che utilizzo principalmente come puntatore intelligente in Qt e lo trovo paragonabile boost:shared_ptr
anche se probabilmente molto più sovraccarico come molti oggetti in Qt.
QWeakPointer
- Senti uno schema ricorrente? Proprio come std::weak_ptr
e boost::weak_ptr
questo è usato insieme a QSharedPointer
quando hai bisogno di riferimenti tra due puntatori intelligenti che altrimenti farebbero sì che i tuoi oggetti non vengano mai cancellati.
QScopedPointer
- Questo nome dovrebbe anche sembrare familiare e in realtà era basato su, a boost::scoped_ptr
differenza delle versioni Qt, di puntatori condivisi e deboli. Funziona per fornire un puntatore intelligente per un singolo proprietario senza il cui sovraccarico QSharedPointer
lo rende più adatto per compatibilità, codice sicuro dalle eccezioni e tutte le cose che potresti usare std::auto_ptr
o boost::scoped_ptr
per.