2012-02-25 13 views
19

Eventuali duplicati:
Deleting pointers in a vectorLo std :: vector chiama il distruttore dei puntatori agli oggetti?

so quando un std::vector è destructed, chiamerà il distruttore di ciascuno dei suoi elementi. Chiama il distruttore di puntatori agli oggetti?

vector<myclass*> stuff; 

Quando la roba viene distrutta, i singoli oggetti puntati dai puntatori all'interno della roba vengono distrutti?

+0

Check out [boost :: ptr_vector ] (http://www.boost.org/doc/libs/1_49_0/libs/ptr_container/doc/ptr_vector.html) –

risposta

30

No.

Come si std::vector suppone di sapere come distruggere la punta-per oggetto? Dovrebbe usare delete? delete[]? free? Qualche altra funzione? Come si deve sapere che gli oggetti appuntiti sono effettivamente allocati dinamicamente o che è l'unico vero proprietario ed è responsabile della loro distruzione?

Se std::vector è l'unico vero proprietario degli oggetti a punta, utilizzare std::unique_ptr, potenzialmente con un deletatore personalizzato per gestire la pulizia degli oggetti.

+1

Se 'std :: vector' avrebbe un costruttore che accetta una funzione di distruzione per gli elementi che sarebbero dandy. Sarebbe utile per legacy o C API. Ma comunque il modo migliore di fare le cose è avvolgere questo tipo di risorse con una classe RAII. – wilhelmtell

+1

@wilhelmtell è possibile scrivere un allocatore personalizzato per quello :) O dare 'unique_ptr' una funzione di delet personalizzata. –

+0

@SethCarnegie sì, mi ha colpito pochi secondi dopo aver postato il commento. mi capita tutto il tempo, parlando prima di pensare. : -S – wilhelmtell

5

No; cosa succede se hai memorizzato un puntatore su un oggetto automatico?

vector<T*> v; 
T tinst; 
v.push_back(&tinst); 

Se il vettore chiama i distruttori degli oggetti i puntatori puntano, l'oggetto automatica sarebbe distrutto due volte - una volta quando è andato fuori portata, e una volta quando il vettore è andato fuori del campo di applicazione. Inoltre, cosa succede se non dovrebbero essere deallocati con delete? Non c'è modo di comportarsi in modo appropriato in ogni situazione.

Se gli oggetti sono tutti allocati dinamicamente, è necessario iterare manualmente il vettore e delete ogni puntatore se è stato allocato con new. In alternativa, è possibile creare un vettore di puntatori intelligenti che sarà rilasciare gli oggetti cui punta il puntatori:

vector<shared_ptr<T>> v; 
v.push_back(new T); 
+0

Hm. Penso che la seconda parola, "perché", sia fuorviante. L'onere di giustificare la cancellazione di pointe non è sul vettore; piuttosto, l'OP deve spiegare perché un contenitore * dovrebbe * trattare gli elementi tipizzati con puntatore in modo diverso. Così com'è, la risposta potrebbe essere un semplice, "No". –

+1

@KerrekSB rimosso poi :) –

15

Come hai detto tu stesso correttamente, il vettore fa distruttori di chiamata per i suoi elementi. Quindi, nel tuo esempio, il vettore chiama "distruttori di puntatori" con. Tuttavia, è necessario tenere presente che i tipi di puntatore non hanno distruttori. Solo i tipi di classe possono avere distruttori. E i puntatori non sono classi. Quindi, è più corretto dire che std::vector applica la sintassi di chiamata pseudo-distruttore agli oggetti puntatori memorizzati nel vettore. Per i tipi di puntatore che risultano in non-operazione, non fa nulla.

Questo risponde anche alla seconda parte della domanda: se gli oggetti myclass puntati dai puntatori vengono distrutti. No, non vengono distrutti.

Inoltre, sembra che tu in qualche modo creda che "chiamare i distruttori sui puntatori" (la prima parte della tua domanda) è la stessa cosa di "distruggere gli oggetti appuntiti" (la seconda parte della tua domanda). In realtà si tratta di due cose non correlate completamente diverse.

Per creare un collegamento dal primo al secondo, ad es.per fare in modo che il vettore distrugga gli oggetti appuntiti, devi costruire il tuo vettore da una sorta di "puntatori intelligenti", in contrasto con i normali puntatori grezzi myclass *. Il vettore chiamerà automaticamente i distruttori dei "puntatori intelligenti" e questi distruttori, a loro volta, distruggeranno gli oggetti appuntiti. Questo "link" può essere implementato solo esplicitamente, all'interno del distruttore del "puntatore intelligente", ed è per questo che i normali puntatori grezzi non possono aiutarti qui.

+0

In realtà se vuoi essere preciso, 'std :: vector' non distrugge nulla, l'allocatore fa –

+0

+1 Haha, molto buono, azzeccato. –

+0

Questa dovrebbe essere la risposta accettata in quanto mostra perché i puntatori non sono casi particolari. –

Problemi correlati