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á virtualy bes un Base*apuntador a un Derivedobjeto, delete btiene 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 virtualcuando 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 deletea 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 .