2012-03-31 7 views
8

¿El destructor predeterminado en las clases de C++ elimina automáticamente los miembros que no están explícitamente asignados en el código? Por ejemplo:cuánto hace el destructor predeterminado

class C { 
    public: 
    C() {} 
    int arr[100]; 
}; 

int main(void) { 
    C* myC = new C(); 
    delete myC; 
    return 0; 
} 

¿Eliminar myC desasignar arr arr myC automáticamente? ¿O necesito escribir el destructor de C para hacer esto explícitamente?

+2

http://www.parashift.com/c++faq-lite/dtors.html – Anycorn

+0

elimina la matriz automáticamente. – JosephH

Respuesta

5

El constructor (en ausencia de ctor-initializer-list) llama al constructor predeterminado para cada subobjeto.

Dado que no tiene clases base y sus variables miembro son tipos primitivos, no hará nada en absoluto.

Lo mismo con el destructor. El suyo es implícitamente generado por el compilador ya que no ha declarado uno, y llamará al destructor para cada subobjeto. De nuevo, eso es trivial porque tu único subobjeto es un agregado de primitivos.

Ahora, toda la memoria de la clase se liberará cuando la elimine. Como la matriz está integrada dentro de la clase, es parte de la misma región de memoria y se liberará al mismo tiempo.

+0

@Mark: no existe una distinción "predeterminada" para los destructores, ya que no se pueden sobrecargar. –

+0

@Mark: no hay problema. –

+0

Por "subobject" te refieres a "miembro de datos", seguramente? –

5

El destructor implícitamente definido (predeterminado) llamará al destructor para cada miembro. En el caso de una matriz de miembros, llamará al destructor para cada elemento de la matriz.

Tenga en cuenta que los punteros no tienen destructores; necesita eliminarlos manualmente No tiene este problema en el ejemplo proporcionado, pero es algo a tener en cuenta.

+1

Punteros tipo de destructores [(vea aquí)] (http://ideone.com/97iUx), aunque obviamente no eliminan lo que señalan. – Pubby

+0

espera ... dices que los punteros no tienen destructores, pero pensé que eliminar solo toma un puntero. ¿Estás diciendo que el destructor predeterminado llamaría eliminar en cada 100 entradas en la matriz? – Robz

+0

@Robz, no, estoy diciendo que el destructor implícito * no * llama a eliminar, usted tiene que hacerlo usted mismo en un destructor explícito si tiene punteros sin formato como miembros. –

5

Si su clase/estructura contiene un puntero y asigna explícitamente algo para que se refiera a ese puntero, normalmente necesitará escribir un delete coincidente en el dtor. Los miembros que están directamente integrados en la clase/estructura se crearán y destruirán automáticamente.

class X { 
    int x; 
    int *y; 
public: 
    X() : y(new int) {} 
    ~X() : { delete y; }  
}; 

Aquí X :: x se creará/destruirá automáticamente. X :: y (o, para ser técnicamente correcto, lo que X :: y señala) no lo asignaremos al codificador y lo destruiremos en el dtor.

+0

'X :: y' se destruye automáticamente. Es' * (X :: y) 'que se filtraría si no fuera por el destructor. (Y tu muestra rompe la regla-de-tres/cuatro/cinco) –

+0

@BenVoigt: Sí, la pregunta era sobre qué hace el destructor, no cómo escribir una clase que maneje correctamente la propiedad remota. –

0

Cualquier cosa que llame nueva debe tener una eliminación correspondiente. Si no llamó a new para crear una instancia de algo, entonces no tiene que llamar a delete.

+0

En mi humilde opinión, rara vez se debe 'eliminar' nada en el código de la aplicación. En su lugar, trate de establecer una propiedad estricta o miembro de semántica para todos los miembros, tal que la destrucción automática no el truco. Si eso falla, los punteros inteligentes suelen ser una mejor alternativa que los punteros manuales y 'eliminar'. – Rawler

-1

No tiene que escribir un destructor. La clase C++ tiene el destructor predeterminado para eliminar el objeto después de 'devolver 0' para reciclar la memoria.