Los destructores virtuales son útiles cuando podría eliminar una instancia de una clase derivada a través de un puntero a la clase base:
class Base
{
// some virtual methods
};
class Derived : public Base
{
~Derived()
{
// Do some important cleanup
}
};
Aquí, notará que no he declarado que el destructor de Base sea virtual
. Ahora, echemos un vistazo al siguiente fragmento:
Base *b = new Derived();
// use b
delete b; // Here's the problem!
Desde destructor de base no está virtual
y b
es un Base*
apuntador a un Derived
objeto, delete b
tiene un comportamiento indefinido :
[En delete b
], si el tipo estático del objeto a eliminar es diferente de su tipo dinámico, el tipo estático será una clase base del tipo dinámico del objeto a eliminar y el tipo estático tendrá un destructor virtual o El comportamiento es indefinido .
En la mayoría de las implementaciones, la llamada al destructor se resolverá como cualquier código no virtual, lo que significa que se llamará al destructor de la clase base pero no al de la clase derivada, lo que provocará una pérdida de recursos.
En resumen, siempre haga los destructores de las clases base virtual
cuando estén destinados a ser manipulados polimórficamente.
Si desea evitar la eliminación de una instancia a través de un puntero de clase base, puede hacer que el destructor de clase base esté protegido y no sea virtual; Al hacerlo, el compilador no le permitirá llamar delete
a un puntero de clase base.
Puede obtener más información sobre virtualidad y destructor de clase base virtual en este artículo de Herb Sutter .