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

c++ - implementar - destructor tortugas ninja



¿Por qué el destructor de la clase se llama dos veces? (5)

Disculpas si la pregunta suena tonta, estaba siguiendo a los expertos en SO y probando algunos ejemplos yo mismo, y este es uno de ellos. Probé la opción de búsqueda pero no encontré una respuesta para este tipo.

class A { public: A(){cout<<"A Contruction"<<endl;} ~A(){cout<<"A destruction"<<endl;} }; int main() { vector<A> t; t.push_back(A()); // After this line, when the scope of the object is lost. }

¿Por qué el destructor de la clase se llama dos veces?


Esto te mostrará lo que está happening :

struct A { A() { cout << "contruction/n"; } A(A const& other) { cout << "copy construction/n"; } ~A() { cout << "destruction/n"; } }; int main() { vector<A> t; t.push_back(A()); }


Hay dos llamadas de destructor porque hay dos objetos: el argumento de push_back y el elemento recién agregado dentro del vector t .

Los contenedores STL almacenan copias. En su ejemplo, el elemento agregado al vector mediante push_back es una copia construida a partir del argumento pasado a push_back . El argumento es A() , que es un objeto temporal, consulte aquí (variante 4) .

Ampliando un poco la respuesta, aunque no la hayas pedido explícitamente: puede ser útil saber cuándo se destruye lo temporal. El estándar ( N4140 ) lo N4140 claramente en 12.2 p3:

... Los objetos temporales se destruyen como último paso en la evaluación de la expresión completa (1.9) que (léxicamente) contiene el punto donde se crearon ...

Nota al emplace_back : si usas emplace_back solo hay un objeto. El nuevo elemento en el contenedor se construye directamente a partir de los argumentos para emplace_back. Muchos contenedores STL aprendieron una variante de emplace en C ++ 11.


Lo más probable es que la copia de su objeto se está creando. Debido a lo cual, el destructor para el objeto copiado y el objeto original hace que el recuento de llamadas sea = 2.

Ejemplo: Aunque está pasando la referencia de objeto, a alguna clase, esto invocaría internamente el constructor de copia. Para evitar esto, la clase secundaria (a la que está pasando la referencia principal, debe ser como;

Parent *const &p parentRef; //Child.h

Entonces, el objeto padre se pasará como;

// Parent.cpp Parent *parentObj = this; Child *childObj = Child(parentObj);

Además, puede depurar la invocación de copia-constructor, anulando;

Parent(const Parent& object){ cout <<"copy called.." << endl; } ...

Más información @@


Para agregar el elemento, se invoca un constructor de copia en un objeto temporal. Después de push_back() el objeto temporal se destruye, esa no es la primera llamada del destructor. Luego, vector instancia de vector queda fuera del alcance y destruye todos los elementos almacenados, esa es la segunda llamada del destructor.


Se llama al destructor una vez cuando se destruye el envío temporal a push_back y una vez cuando se destruye el elemento en t .