Exercícios Resolvidos de Mais herança e mais polimorfismo

Ver Teoria

Enunciado

Os dois códigos abaixo implementam duas classes com herança e polimorfismo. A única diferença entre eles está na linha 07.

Como essa diferença impacta o uso de ponteiros? Escreva um código que mostre essa diferença.

Passo 1

Vamos nessa!

A única diferença entre os dois códigos é que na linha 06 o Código A utiliza a palavra chave v i r t u a l e o código B não utiliza

Isso quer dizer que no código A o método T e x t o (   ) é um método virtual, e no código B não.

Os métodos virtuais são uma forma de mudar o comportamento de um método que vai sofrer polimorfismo.

A mudança de comportamento acontece quando existe iterações entre a classe mãe e a classe filha de uma das duas formas:

  1. Quando um método que sofreu polimorfismo na classe filha é executando dentro de outro método da classe mãe.
  2. Quando usamos ponteiros da classe mãe para armazenar o endereço de um objeto da classe filha.

O v i r t u a l informa ao C++ que ele sempre deve olhar pra classe filha em busca de polimorfismos. Caso o virtual não esteja presente, quando a gente executar um dos dois casos acima, a versão “polimorfada” será ignorada, e a versão da classe mãe será executada.

De certa forma é como se quando a gente não usa o v i r t u a l o polimorfismo só tem validade dentro da classe Filha, e métodos e ponteiro da classe mãe não vão levar o polimorfismo em conta.

Para ficar mais claro. Vamos executar os códigos A e B

Passo 2

Primeiro vamos executar o Código A que utiliza o v i r t u a l

Então vamos fazer o seguinte. Dentro da m a i n ( ) vamos declarar um ponteiro para classe M a e chamdo p n t _ M a e , e um objeto da classe F i l h a chamado o b j e t o F i l h a .

Em seguida, vamos guardar o endereço de o b j e t o F i l h a no ponteiro p n t _ M a e

E pra terminar vamos executar o método T e x t o duas vezes. A primeira vez vamos executar através do ponteiro, e a segunda vez vamos executar através do objeto.

Usando o v i r t u a l os resultados são iguais! Nos dois casos a versão “polimorfada” é executada. Isso acontece pois o v i r t u a l informa ao C++ que o método T e x t o ( ) pode sofrer polimorfismo, então quando usamos um ponteiro da classe mãe para apontar para a classe filha o C++ está ciente que deve buscar por um polimorfismo do método T e x t o ( ) .

Passo 3

E agora vamos executar o Código B que não utiliza o v i r t u a l

Quando não usamos o v i r t u a l os resultados são diferentes! A chamada através de ponteiro executa a versão da classe mãe, e a chamada através de objeto executa a versão “polimorfada” da classe filha.

Isso acontece pois, sem o v i r t u a l , não existe nenhum aviso da possibilidade de polimorfismo, então, o C++ não se preocupa em conferir se existe polimorfismo do método T e x t o , e simplesmente executa a versão da classe mãe.

Já quando utilizamos diretamente o objeto da classe filha, nós conseguimos executar a versão com polimorfismo, pois estamos fazendo uma chamada direta a esse objeto, enquanto o ponteiro faz uma chamada indireta.

Resposta

Quando o v i r t u a l não está presente, ao executar uma chamada de um objeto da classe filha através de ponteiro da classe mãe, a versão com polimorfismo será ignorada, e a versão da classe mãe será executada.