2013-05-22 12 views
5

Sto lavorando a qualcun altro codice che contiene un sacco di dichiarazioni come questoauto_ptr, immediato get() e release() - è utile?

std::auto_ptr<ObjectA> smartptr(new ObjectA(this)); 
objects_list.push_back(smartptr.get()); 
smartptr.release(); 

Questo è anche utile? C'è qualche motivo pratico utilizzare un puntatore intelligente qui invece di scrivere

objects_list.push_back(new ObjectA(this)); 
+0

'std :: auto_ptr' è utile. Non è così utilizzabile. –

+0

Cosa succede se 'object_list' lancia quando ricresce? Inoltre, 'std :: auto_ptr' è C++ 03, quindi ho rimosso il tag C++ 11. – Xeo

risposta

13
objects_list.push_back(new ObjectA(this)); 

Questo può perdere memoria. Vediamo cosa succede quando noi spezziamo giù:

  • new ObjectA(this) è assegnato
  • push_back viene poi chiamato

Tuttavia, push_back può lanciare e se lo fa, il tuo new ObjectA è trapelato.

Il codice auto_ptr che ci hai mostrato risolve questo problema: se push_back gira, il puntatore è ancora di proprietà di auto_ptr e non si verificano perdite.


La vera soluzione sarebbe quella di memorizzare puntatori intelligenti direttamente nel contenitore invece di puntatori nude (perché puntatori nude in contenitori sono mal di testa quando si tratta di garantire gli oggetti siano correttamente cancellato).

Sfortunatamente con C++ 03 (da cui deriva auto_ptr, è stato deprecato in C++ 11) non è possibile memorizzare auto_ptr in contenitori (il motivo è gravemente danneggiato). È possibile memorizzare boost::shared_ptr in contenitori o passare a C++ 11 e memorizzare unique_ptr o shared_ptr.

2

L'idea era probabilmente quello di evitare perdite di memoria nel caso del vettore push_back getta. Ciò potrebbe accadere se i vettori devono essere trasferiti e non riesce ad allocare più memoria.

+0

Oppure se copia/sposta i corpi degli oggetti lanciati. – Xeo

+2

Xeo: Se una copia o lo spostamento di un valore di puntatore si getta sei comunque avvitato –

+0

Chi dice che 'object_list' memorizza effettivamente i puntatori? Forse memorizza qualcosa che è implicitamente costruibile da 'ObjectA *'? :) – Xeo

1

Fornisce sicurezza rispetto alle eccezioni. Nel primo esempio, l'oggetto assegnato verrà eliminato se push_back non riesce; nel secondo esempio, perde.

Si noti che, dal 2011, auto_ptr è deprecato a favore di unique_ptr. Questo ha il vantaggio di poter essere memorizzato nel vettore, alleviandoti dal peso dell'eliminazione manuale degli oggetti quando li rimuovi dal vettore.