c++ - implementar - destructor tortugas ninja
¿Necesito llamar explícitamente al destructor virtual base? (6)
Lo que dijeron los demás, pero también tenga en cuenta que no tiene que declarar el destructor virtual en la clase derivada. Una vez que declare un destructor virtual, como lo hace en la clase base, todos los destructores derivados serán virtuales, tanto si los declara como si no. En otras palabras:
struct A {
virtual ~A() {}
};
struct B : public A {
virtual ~B() {} // this is virtual
};
struct C : public A {
~C() {} // this is virtual too
};
Al anular una clase en C ++ (con un destructor virtual), estoy implementando el destructor nuevamente como virtual en la clase hereditaria, pero ¿debo llamar al destructor base?
Si es así me imagino que es algo como esto ...
MyChildClass::~MyChildClass() // virtual in header
{
// Call to base destructor...
this->MyBaseClass::~MyBaseClass();
// Some destructing specific to MyChildClass
}
Estoy en lo cierto
No, los destructores son llamados automáticamente en el orden inverso de construcción. (Últimas clases de base). No llames destructores de clase base.
No, no es necesario que llame al destructor base, el destructor derivado siempre invoca un destructor base. Por favor vea mi respuesta relacionada aquí para el orden de destrucción .
Para comprender por qué quiere un destructor virtual en la clase base, consulte el siguiente código:
class B
{
public:
virtual ~B()
{
cout<<"B destructor"<<endl;
}
};
class D : public B
{
public:
virtual ~D()
{
cout<<"D destructor"<<endl;
}
};
Cuando tu lo hagas:
B *pD = new D();
delete pD;
Entonces, si no tenía un destructor virtual en B, solo se llamaría ~ B (). Pero como tienes un destructor virtual, primero se llamará ~ D (), luego ~ B ().
No, nunca llamas al destructor de la clase bese, siempre se llama automáticamente como otros lo han señalado, pero aquí hay una prueba de concepto con resultados:
class base {
public:
base() { cout << __FUNCTION__ << endl; }
~base() { cout << __FUNCTION__ << endl; }
};
class derived : public base {
public:
derived() { cout << __FUNCTION__ << endl; }
~derived() { cout << __FUNCTION__ << endl; } // adding call to base::~base() here results in double call to base destructor
};
int main()
{
cout << "case 1, declared as local variable on stack" << endl << endl;
{
derived d1;
}
cout << endl << endl;
cout << "case 2, created using new, assigned to derive class" << endl << endl;
derived * d2 = new derived;
delete d2;
cout << endl << endl;
cout << "case 3, created with new, assigned to base class" << endl << endl;
base * d3 = new derived;
delete d3;
cout << endl;
return 0;
}
La salida es:
case 1, declared as local variable on stack
base::base
derived::derived
derived::~derived
base::~base
case 2, created using new, assigned to derive class
base::base
derived::derived
derived::~derived
base::~base
case 3, created with new, assigned to base class
base::base
derived::derived
base::~base
Press any key to continue . . .
Si establece el destructor de la clase base como virtual cuál debería, entonces los resultados son los mismos que en el caso 1 y 2.
No. A diferencia de otros métodos virtuales, donde llamaría explícitamente al método Base desde Derivado para "encadenar" la llamada, el compilador genera código para llamar a los destructores en el orden inverso en que fueron llamados sus constructores.
No. Se llama automáticamente.