tortugas implementar herencia destructores delete creative constructores como c++ destructor

c++ - implementar - destructor tortugas ninja



Destructor se llama dos veces cuando se invoca explícitamente (10)

Estaba experimentando con destructores en C ++ con este código:

#include <iostream> struct temp { ~temp() { std::cout << "Hello!" << std::endl; } }; int main() { temp t; t.~temp(); }

Veo que "¡Hola!" Se está imprimiendo dos veces. ¿No debería la llamada del destructor liberar el objeto y no debería volver a llamarse al destructor cuando está fuera de alcance? ¿O hay algún otro concepto?

(No pretendo hacer esto en la práctica. Solo estoy tratando de entender lo que está pasando aquí).


Veo que "¡Hola!" Se está imprimiendo dos veces. ¿no debería la llamada del destructor liberar el objeto y el destructor no debería volver a llamarse cuando está fuera de alcance? ¿O hay algún otro concepto?

Eso es correcto.

Debo mencionar que no pretendo hacer esto en la práctica. Estoy tratando de entender qué está pasando aquí.

Has llamado al destructor, preparando un objeto para ser destruido. Pero esto también se hace automáticamente cuando un objeto queda fuera del alcance, antes de que sea realmente desasignado.

Lo que hay que entender es esto: si haces cosas que no tienen sentido, entonces suceden cosas malas. Así que no hagas cosas que no tienen sentido. Si llama manualmente a un destructor, el descriptor se ejecuta. Eso no tiene efecto en ninguna otra cosa a menos que el destructor haga algo que tenga un efecto.


Destructor está destinado a ser llamado cuando un objeto sale del ámbito si el objeto está en la pila como en este caso o cuando se destruye explícitamente con eliminar cuando el objeto se crea en el montón con un nuevo operador en primer lugar.

No hay forma de que el compilador o el sistema de tiempo de ejecución no pierdan de vista si usted llama al destructor manualmente o no. También es una muy mala práctica hacer una llamada al destructor.

Si desea realizar una limpieza manual (que no sea el objeto que se elimina de la memoria o que se elimina de la pila) antes de que se elimine el objeto, puede hacer algo como esto.

Aquí desea permitir que el cliente limpie las cosas manualmente, incluso antes de que se elimine el objeto. Pero además de eso, usted limpia las cosas si el cliente no las limpia.

class A { public: A() : _closed(false) {} ~A() { close(); } void close() { if (! _closed()) { // close file handles etc. } } private: bool _closed }


El destructor de una clase podría ser invocado:

  1. Explícitamente

    Cuando el destructor se invoca explícitamente utilizando el objeto de la clase, de la misma manera se invoca a otra función miembro de la clase.

  2. Implícitamente

    Cuando el objeto de la clase queda fuera del alcance o un objeto creado con el nuevo operador se destruye con el operador de eliminación.

En tu programa de muestra, haces ambas cosas.

int main() { temp t; t.~temp(); //1. Calling destructor explictly using the object `t` return 0; } // 2. object `t` goes out of scope. So destructor invoked implictly

y esa es la razón por la que ves que el destructor es llamado dos veces.

Como habrás pensado acertadamente, el destructor destruirá los recursos creados por el constructor. Por lo tanto, no se debe llamar explícitamente al destructor, ya que resultará en la destrucción del recurso ya destruido y eso podría ser fatal.


El destructor no es el "destructor" del objeto. Es solo una función ordinaria, pero es llamada automáticamente por el lenguaje inmediatamente antes del momento de la destrucción.

Su nombre oficial es el destructor, pero tal vez sería más fácil de entender si lo llamáramos la función "Antes de la destrucción".


Llamar al destructor no libera el objeto.

El destructor está allí para limpiar las partes internas del objeto y luego el objeto en sí se libera una vez que el destructor termina.

Es un error hacer lo que está haciendo de manera similar a la forma en que puede llamar a eliminar dos veces en un objeto, pero es un error hacerlo.

Hay solo unos pocos casos en los que quieres llamar al destructor manualmente y este no es uno de ellos. Realmente está ahí para las veces que construyes manualmente un objeto en una ubicación de memoria usando la ubicación nueva y luego necesitas poder destruirlo sin liberar la memoria.



No llama explícitamente al destructor, se llama automáticamente cuando la variable sale del ámbito (aquí después de la return 0; declaración). Por eso se llama dos veces, se llama y luego el sistema lo llama.

Si desea poder eliminar una instancia de esta clase, explícitamente, debe asignarla dinámicamente:

temp *t = new temp; // do stuff with t... delete t; // do not forget this, or the constructor is not being called at all


No necesitarás llamar a un destructor, aunque es posible hacerlo. El compilador debe ejecutar implícitamente su destructor cuando un objeto ya no se utiliza. Cuando se crean objetos, su constructor se utiliza para ese objeto, si se ha declarado con valores específicos e inicializados para los miembros de su clase. Cuando ya no necesite su objeto, su destructor ejecutará y eliminará las declaraciones de las variables miembro y sus valores. Esto es más útil para los idiomas que no utilizan la recolección automática de basura, como C ++.


Simplemente llama al destructor, en realidad no libera ninguna memoria (está asignada estáticamente). Si usas nuevo y luego eliminas el destructor solo se llamará una vez.


Sucede porque le dijiste que sucediera. El destructor para una variable automática siempre se llama cuando la variable está fuera de alcance. Tú también lo llamaste. Esas son dos llamadas en total.

Llamar al destructor de un objeto no indica a C ++ que no lo vuelva a llamar, ya que en la ejecución normal no es necesario realizar un seguimiento.

La solución es nunca llamar manualmente a tu destructor.