Considerações virtuais em C ++

Você precisa ter em mente algumas coisas ao usar funções virtuais em C ++. Em primeiro lugar, as funções de membro estático não pode ser declarado virtual. Como as funções de membro estático não são chamados com um objeto, não há nenhum objeto de tempo de execução sobre o qual basear uma decisão vinculativa.

Em segundo lugar, especificando o nome da classe na chamada força uma chamada para ligar mais cedo, se quer ou não a função é virtual. Por exemplo, o seguinte é a chamada Base de Dados :: fn () porque é isso que o programador indicado, mesmo se fn () é declarado virtual:

void test (Base b) {b.Base :: fn () - // esta chamada não está vinculada final}

Finalmente, os construtores não pode ser virtual porque não existe (completo) objeto a ser usado para determinar o tipo. Na época, o construtor é chamado, a memória que o objeto ocupa é apenas uma massa amorfa. É somente depois que o construtor tenha terminado que o objeto é um membro da classe em boas condições.

Em comparação, o destruidor quase sempre deve ser declarado virtual. Se não, você corre o risco de destructing indevidamente o objeto, como na seguinte circunstância:

Classe base {public: ~ Base () -} - CLASSE Subclasse: Base de dados pública {public: ~ SubClass () -} - vazio finishWithObject (Base * pHeapObject) {// ... trabalhar com objeto ... // agora retorno -lo para o heapdelete pHeapObject- // isto chama base de ~ () não importa} // o tipo de tempo de execução de // pHeapObject

Se o ponteiro passado para finishWithObject () realmente aponta para um SubClass, a SubClass destructor não é invocado corretamente - porque o processo de destruição não foi declarado virtual, é sempre obrigado cedo. Declarar a destruição virtual resolve o problema.

Então, quando você não quer declarar o destruidor virtual? Há apenas um caso. funções virtuais introduzir um # 147-pouco # 148- sobrecarga.

Mais especificamente: Quando o programador define a primeira função virtual em uma classe, C ++ adiciona um ponteiro adicional, escondido - e não um ponteiro per função virtual, apenas um ponteiro, se a classe tem quaisquer funções virtuais. Uma classe que não tem funções virtuais (e não herda todas as funções virtuais a partir de classes base) não tem esse ponteiro.

Agora, um ponteiro não parecer muito, e não é menos que as duas condições que se seguem:

  • A classe não tem muitos membros de dados (para que um ponteiro representa muito em comparação com o que já está lá).

  • Você pretende criar um monte de objetos desta classe (caso contrário, a sobrecarga não faz qualquer diferença).

Se estas duas condições sejam atendidas e sua classe já não tem funções membro virtuais, você pode não querer declarar a destruição virtual.

Exceto por este caso, sempre declarar destruidores de ser virtual, mesmo se a classe não é (ainda) uma subclasse - você nunca sabe quando alguém vai vir e usar sua classe como a classe base para o seu próprio. Se você não declarar o destruidor virtual, em seguida, declarar a classe final (se o seu compilador suporta esta funcionalidade) e documentá-lo!

menu