2011-01-26 10 views
5

Di tanto in tanto, per i momenti fugaci, penso auto_ptr è cool. Ma la maggior parte delle volte riconosco che ci sono tecniche molto più semplici che la rendono irrilevante. Ad esempio, se voglio che un oggetto venga liberato automaticamente, anche se viene lanciata un'eccezione, potrei creare nuovamente l'oggetto e assegnarlo a un auto_ptr. Molto bello! Ma avrei potuto creare più facilmente il mio oggetto come variabile locale e lasciare che lo stack si occupasse di esso (duh!).Lasciar andare auto_ptr

Così non ero troppo sorpreso quando ho scoperto google C++ coding standards vieta l'uso di auto_ptr. Google afferma che deve essere usato scoped_ptr (se è necessario un puntatore intelligente).

Mi piacerebbe sapere se qualcuno, contrariamente alla mia esperienza, può dare una solida ragione/i di quando auto_ptr è la cosa migliore o più semplice da usare. In caso contrario, suppongo che ne escluderò l'utilizzo da solo (seguendo la guida di Google).

aggiornamento: Per coloro che hanno espresso preoccupazione, no non sto adottando gli standard di Google. Ad esempio, contro il consiglio di google, sono d'accordo che la gestione delle eccezioni debba essere attivata. Mi piace anche l'utilizzo di macro di preprocessore, come ad esempio il printable enum creato. È solo l'argomento auto_ptr che mi ha colpito.

update2: Risulta che la mia risposta proviene da due dei risponditori di seguito, e uno note from Wikipedia. Innanzitutto, Herb Sutter ha mostrato un uso valido (idioma del sink di origine e composizione di oggetti con collegamento a vita). In secondo luogo, ci sono negozi dove TR1 e boost non sono disponibili o bannati e solo C++ 03 è permesso. Terzo, secondo Wikipedia, la specifica C++ 0x sta deprecando auto_ptr e lo sostituisce con unique_ptr. Quindi la mia risposta è: usa unique_ptr se disponibile per me (su tutte le piattaforme in considerazione) altrimenti usa auto_ptr per i casi rappresentati da Sutter.

+3

La guida di stile di Google vieta anche le eccezioni. Escluderemo le eccezioni perché qualcuno sbaglia loro e la guida allo stile di Google vieta? No. – sharptooth

+3

non seguono le linee guida di Google, in generale, sono specifiche per loro e includono la necessità di integrazione con il loro enorme numero di codice C. (Ci sono molti motivi per non usare 'auto_ptr'). –

risposta

7

E 'la cosa più semplice da usare quando si ha bisogno di un puntatore di ambito o di unico e si lavora in un ambiente rigoroso C++ 03 che non hanno accesso ad un'implementazione TR1 o di spinta.

+0

+100 se potessi –

1

Beh, una ragione potrebbe essere che scoped_ptr non è copiabile, quindi è più sicuro da usare e più difficile da fare errori con. auto_ptr consente il trasferimento della proprietà (ad esempio passandogli un altro auto_ptr come parametro costruttore). Se hai bisogno di pensare a cose come trasferire la proprietà, è probabile che tu stia meglio con un puntatore intelligente come shared_ptr.

3

std::auto_ptr ha ancora la semantica puntatore, in modo (non-puntatore) automatici variabili non sono un sostituto. In particolare, std::auto_ptr supporta il polimorfismo e la riassegnazione. Con le variabili stack è possibile utilizzare i riferimenti per il polimorfismo, ma i riferimenti non consentono la riassegnazione.

volte std::auto_ptr farà bene. Ad esempio, per l'implementazione di un pimpl. È vero, nella stragrande maggioranza dei casi, la libreria di puntatori intelligenti offre scelte migliori per un puntatore intelligente. Ma adesso std::auto_ptr è una soluzione standard, mentre i puntatori intelligenti di boost non lo sono.

2

Utilizzando auto_ptr come valore di ritorno della funzione si gode senza copiyng spese generali e non hanno mai perdita di memoria. std::auto_ptr<obj> foo() può essere tranquillamente chiamato in { foo(); } mentre obj *foo() non può. boost :: shared_ptr può risolvere questo problema, ma con un sovraccarico maggiore.

Inoltre, alcuni oggetti non possono essere creati sulla pila a causa di vincoli di memoria: stack di thread sono relativamente piccoli.Ma boost :: scoped_ptr è migliore in questo caso poiché non può essere rilasciato accidentalmente.

6

Mentre divieto auto_ptr sembra attraente, ma c'è un problema:

template <typename T> 
some_smart_ptr<T> create(); 

Che cosa intende sostituire il some_smart_ptr segnaposto con?

La risposta generica, shared_ptr, vale solo se la proprietà è realmente condivisa, se la funzione concede al chiamante la proprietà esclusiva delle risorse, è fuorviante al meglio (e un caso tipico di pessimizzazione prematura per quanto mi riguarda ha riguardato).

D'altra parte, in C++ 03, nessun'altra forma di puntatore intelligente può fornire: è impossibile, senza spostare la semantica, fornire ciò che vorremmo qui. auto_ptr o un puntatore nudo sono i due contendenti logici. Ma poi un puntatore nudo ti espone al rischio di perdite se il chiamante è distratto.

Con C++ 0x, unique_ptr vantaggiosamente sostituire auto_ptr in ogni situazione.