Tengo uno class A
que usa una asignación de memoria de montón para uno de sus campos. La clase A se instancia y se almacena como un campo de puntero en otra clase ( class B
.
Cuando termino con un objeto de clase B, llamo delete
, que supongo que llama al destructor ... ¿Pero esto también llama al destructor de la clase A?
Editar:
De las respuestas, tomo eso (edite si es incorrecto):
delete
de una instancia de B llama a B :: ~ B ();- que llama
A::~A();
A::~A
debería explícitamentedelete
todas las variables miembro asignadas en el montón del objeto A;- Finalmente, el bloque de memoria que almacena dicha instancia de clase B se devuelve al montón: cuando se usó nuevo , primero asignó un bloque de memoria en el montón, luego invocó a los constructores para inicializarlo, ahora después de que se hayan invocado todos los destructores para finalizar el objeto, el El bloque donde residía el objeto se devuelve al montón.
fuente
++
operador en él. Entonces, me pregunto si el puntero que apunta en el medio de los datos de la clase todavía tiene el efecto.Cuando llame a delete en un puntero asignado por new, se llamará al destructor del objeto señalado.
fuente
Se llama "destructor", no "deconstructor".
Dentro del destructor de cada clase, debe eliminar todas las demás variables miembro que se han asignado con nuevo.
editar: Para aclarar:
Di que tienes
Asignar una instancia de B y luego eliminar es limpio, porque lo que B asigna internamente también se eliminará en el destructor.
Pero las instancias de la clase C perderán memoria, porque asigna una instancia de A que no libera (en este caso, C ni siquiera tiene un destructor).
fuente
Si tiene un puntero habitual (
A*
), no se llamará al destructor (y la memoria, porA
ejemplo, tampoco se liberará) a menos que lo hagadelete
explícitamente enB
el destructor. Si quieres la destrucción automática, mira los punteros inteligentes comoauto_ptr
.fuente
Debe eliminar A usted mismo en el destructor de B.
fuente
Cuando tu lo hagas:
Se llamará al destructor solo si su clase base tiene la palabra clave virtual.
Entonces, si no tuviera un destructor virtual, solo se llamaría ~ B (). Pero como tiene un destructor virtual, primero se llamará a ~ D (), luego a ~ B ().
Ningún miembro de B o D asignado en el montón se desasignará a menos que los elimine explícitamente. Y eliminarlos también llamará a su destructor.
fuente
Tienes algo como
Si luego llama
delete b;
, no le pasa nada a, y tiene una pérdida de memoria. Intentar recordardelete b->a;
no es una buena solución, pero hay un par de otras.Este es un destructor para B que eliminará a. (Si a es 0, esa eliminación no hace nada. Si a no es 0 pero no apunta a la memoria de nuevo, se daña el montón).
De esta manera, no tiene un puntero, sino un auto_ptr <> (shared_ptr <> también lo hará, u otros punteros inteligentes), y se elimina automáticamente cuando b lo es.
Cualquiera de estas formas funciona bien, y he usado ambas.
fuente
Me preguntaba por qué no se llamó al destructor de mi clase. La razón fue que olvidé incluir la definición de esa clase (#include "class.h"). Solo tenía una declaración como "clase A"; y el compilador estaba contento con él y me dejó llamar "borrar".
fuente
No. el puntero se eliminará. Debe llamar a la eliminación en A explícita en el destructor de B.
fuente
El destructor para el objeto de la clase A solo se llamará si se llama a delete para ese objeto. Asegúrese de eliminar ese puntero en el destructor de la clase B.
Para obtener un poco más de información sobre lo que sucede cuando se invoca eliminar en un objeto, consulte: http://www.parashift.com/c++-faq-lite/freestore-mgmt.html#faq-16.9
fuente
no, no llamará al destructor para la clase A, debe llamarlo explícitamente (como le dijo PoweRoy), elimine la línea 'delete ptr;' en ejemplo para comparar ...
fuente