2012-09-30 29 views
6

mirada a este código:¿Por qué C++ std :: list :: clear() no llama a destructores?

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; 
} 

Y luego, mira a esta salida:

Constructor 
    Destructor 
    Contructor 
    1 
    0 

La pregunta es: ¿Por qué es el destructor del elemento de lista no se llama al l.clear()?

Respuesta

12

Su lista es de punteros. Los punteros no tienen destructores. Si desea llamar al destructor, intente con list<test>.

+0

Bien, eso es lo que pensé pero quería confirmarlo. – danikaze

+0

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

+1

Sí, uso SmartPointers para la mayoría de las cosas, pero a veces los punteros crudos son mejores. La cosa es que pensé que si tenía un puntero p, se llamaba delete (p) ... pero sabiendo esto ahora está bien. Voy a liberar punteros sin procesar. – danikaze

3

Una mejor alternativa para liberar punteros usando delete, o usar algo que abstraiga eso (como punteros inteligentes o contenedores de puntero), es simplemente crear los objetos directamente en la pila.

Debería preferir test t; sobre test * t = new test(); Es muy raro que desee tratar con cualquier puntero que posea un recurso, inteligente o no.

Si tuviera que usar un std::list de elementos 'reales', en lugar de punteros a elementos, no tendría este problema.

Cuestiones relacionadas