
Estou abrindo esse tópico para iniciar um estudo de herança virtual e polimorfismo. O programa que coloco como exemplo, está rodando sem problemas. O objetivo, é transpor a idéia do gráfico para o programa, buscando se chegar a um exemplo prático de polimorfismo. Aqueles que quiserem poderão alterar o programa para que represente o gráfico. Após o programa, colocarei algumas perguntas sobre o tema.
O programa
#include <iostream>
using std::cout;
using std::endl;
class B1
{
int atr_b1;
public:
B1(){cout<<"Construtor B1"<<endl;};
~B1(){cout<<"Destrutor B1"<<endl;};
};
class B2
{
int atr_b2;
public:
B2(){cout <<"Construtor B2"<<endl;};
~B2(){cout <<"Destrutor B2"<<endl;};
};
class D1: public B2, virtual public B1
// Os métodos virtuais devem ter exatamente o mesmo protótipo, se o nome for
// igual e os parâmetros diferentes, teremos sobrecarga de métodos.
//O uso de métodos virtuais em heranças permite a implementação do conceito de
//polimorfismo e elimina boa parte das estruturas switch.
{
public:
D1(){cout<<"Construtor D1"<<endl;};
~D1(){cout<<"Destrutor D1"<<endl;};
};
class D2: public B2, virtual public B1
{
public:
D2(){cout<<"Construtor D2"<<endl;};
~D2(){cout<<"Destrutor D2"<<endl;};
};
class Top: public D1, virtual public D2
{
public:
Top(){cout<<"Construtor Top"<<endl;};
~Top(){cout<<"Destrutor Top"<<endl;};
};
int main()
{
Top p;
system ("pause"
return 0;
}
/*A sequência de criação do objeto p é dada por:
Primeiro a sequência de D2 que é virtual: cria B1 que é virtual, cria B2 e então cria D2.
Depois a sequência de D1 que é normal: B1 é virtual pelo caminho Top:2::B1 e já foi criado, cria B2 e depois cria D1. Finalmente cria Top.Ou seja, os construtores default das classes virtuais são chamados antes dos das classes não virtuais.
3Releia a frase acima, veja que escrevi os construtores default das classes virtuais. Se a classe base virtual não tem um construtor default, um dos construtores com parâmetros deve ser explicitamente
chamado. Lembre-se, toda classe tem um construtor default, sem parâmetros, que é criado automaticamente pelo compilador. Vimos que você pode reescrever o construtor da forma que quiser, e que se você criar qualquer construtor com parâmetros, o construtor default deixa de ser criado pelo compilador. Como o construtor default deixa de ser criado, o construtor existente precisa ser explicitamente chamado.*/
Veja o gráfico no fim deste post.
1) Com base no gráfico, e no 1o comentário que diz:
// Os métodos virtuais devem ter exatamente o mesmo protótipo, se o //nome for igual e os parâmetros diferentes, teremos sobrecarga de //métodos.Como podemos adaptar o programa acima para ermos um polimorfismo ?
//O uso de métodos virtuais em heranças permite a implementação do //conceito depolimorfismo e elimina boa parte das estruturas switch.
2) O que se quer dizer, quando se diz que polimorfismo elimina grande quantidade de switchs ?
3) Suponha que eu tenha as chamadas da função abaixo:
FuncA ( int x, int y);
FuncA ( float x, float y);
Eu teria uma sobrecarga por manter o nome dos parâmetros e mudar o tipo do atributo ou dado ? que situação eu teria se mantivesse o tipo de um parâmetro e mudasse outro EX:.
FuncA ( int x, int y);
FuncA ( float x, int y);
4) Com base nos dados da pergunta 3, qual seria a forma correta de se representar um polimorfismo ?
5) Qual a vantagem de se usar herança virtual ?
6) As classes que tem métodos virtuais, contém uma tabela chamada Virtual Memory Table (VMT, ou tabela de métodos virtuais). Vide programa acima. Como isso funciona ?
Obrigado