2012-09-30 12 views
6

Guardate questo codice:Perché C++ std :: list :: clear() non chiama i distruttori?

class test 
{ 
    public: 
     test() { cout << "Constructor" << endl; }; 
     virtual ~test() { cout << "Destructor" << endl; }; 
}; 

int main(int argc, char* argv[]) 
{ 
    test* t = new test(); 
    delete(t); 
    list<test*> l; 
    l.push_back(DNEW test()); 
    cout << l.size() << endl; 
    l.clear(); 
    cout << l.size() << endl; 
} 

E poi, guarda questa uscita:

Constructor 
    Destructor 
    Contructor 
    1 
    0 

La domanda è: perché è il distruttore dell'elemento elenco non chiamato a l.clear()?

risposta

12

L'elenco è di puntatori. I puntatori non hanno distruttori. Se vuoi che il distruttore venga chiamato dovresti provare invece con lo list<test>.

+0

Bello, è quello che pensavo ma volevo confermarlo. – danikaze

+0

Oppure utilizzare Boost.PointerContainer's ['ptr_list'] (http://www.boost.org/doc/libs/release/libs/ptr_container/doc/ptr_list.html). –

+1

Sì, uso SmartPointers per la maggior parte delle cose, ma a volte i puntatori grezzi sono migliori. La cosa è che ho pensato che se avessi un puntatore p, delete (p) è stato chiamato ... ma sapendo questo ora va bene. Libererò i puntatori grezzi. – danikaze

3

Un'alternativa migliore per liberare i puntatori che usano delete, o usare qualcosa che lo astrae (come puntatori intelligenti o contenitori di puntatore), è semplicemente creare gli oggetti direttamente nello stack.

Si consiglia di utilizzare su test * t = new test(); Molto raramente si desidera gestire qualsiasi puntatore che possiede una risorsa, intelligente o meno.

Se si dovesse utilizzare uno std::list di elementi "reali" anziché i puntatori agli elementi, non si avrebbe questo problema.

Problemi correlati