Quando usar os destruidores virtuais?

Eu tenho um sólido entendimento da maioria da teoria OO, mas a única coisa que me confunde muito são os destruidores virtuais.

Pensei que o destruidor é sempre chamado não importa o quê e para cada objecto da cadeia.

Quando é que os deves tornar virtuais e porquê?

Solução

Os destruidores virtuais são úteis quando você pode potencialmente excluir uma instância de uma classe derivada através de um ponteiro para a classe base:

class Base 
{
    // some virtual methods
};

class Derived : public Base
{
    ~Derived()
    {
        // Do some important cleanup
    }
};

Aqui, você'vai notar que eu não declarei'o destruidor da Base'como sendo 'virtual'. Agora, deixe's dar uma olhada no seguinte trecho:

Base *b = new Derived();
// use b
delete b; // Here's the problem!

Como Base's destructor não é virtual e b é um Base* que aponta para um objeto Derived, delete b tem comportamento indefinido:

[Em delete b], se o tipo estático do o objeto a ser apagado é diferente do seu tipo dinâmico, o estático o tipo deve ser uma classe base do tipo dinâmico do objeto a ser apagado e o tipo estático deve ter um destruidor virtual ou o o comportamento é indefinido.

Na maioria das implementações, a chamada ao destruidor será resolvida como qualquer código não-virtual, o que significa que o destruidor da classe base será chamado, mas não o da classe derivada, resultando em um vazamento de recursos.

Resumindo, sempre faça classes base' destruidores virtuais quando're destinados a serem manipulados polimorficamente.

Se você quiser evitar a exclusão de uma instância através de um ponteiro de classe base, você pode tornar a classe base destrutora protegida e nãovirtual; ao fazer isso, o compilador ganhou'não deixe você chamar delete em um ponteiro de classe base.

Você pode aprender mais sobre virtualidade e destruidor de classes base virtuais em este artigo de Herb Sutter.

Comentários (10)

Declare destruidores virtuais em classes de base polimórficas. Este é o Item 7 em Scott Meyers' Effective C++. Meyers continua para resumir que se uma classe tem qualquer função virtual, ela deve ter um destruidor virtual, e que classes não projetadas para serem classes base ou não projetadas para serem usadas polimorficamente devem não declarar destruidores virtuais.

Comentários (7)

Faça o destruidor virtual sempre que a sua aula for polimórfica.

Comentários (0)