O polimorfismo é crucial para a programação orientada a
objeto. Quando aplicado ao C++, o termo polimorfismo é usado para
descrever o processo pelo qual diferentes implementações de uma
função podem ser acessadas usando o mesmo nome.
Assim o polimorfismo também é caracterizado como "uma interface,
múltiplos métodos". Em C++ o polimorfismo é suportado
tanto em tempo de compilação com execução.
Sobrecarga de operadores e de funções são exemplos de
polimorfismo em tempo de compilação. O polimorfismo em tempo de
execução no C++ é obtido com classes derivadas e
funções virtuais.
Ponteiros para tipos bases e tipos derivados estão relacionados. Se
você tem um tipo base chamado B_class e um tipo D_class derivado de
B_class. Em C++ qualquer ponteiro declarado como ponteiro para B_class
também pode ser ponteiro para D_class.
B_class *p; // ponteiro para um objeto do tipo B_class B_class B_obj; //Objeto do tipo B_class D_class D_obj; //Objeto do tipo D_class derivado de B_classUsando p todos os elementos de D_obj herdados de B_obj podem ser acessados. Os elementos específicos de D_obj não podem ser acessados usando-se p. (a menos que se use um molde de tipo, a ser visto posteriormente). O exemplo que segue ilustra os conceitos:
o seguinte é perfeitamente válido:
p= &B_obj; //p aponta para um objeto di tipo B_class p=&D_obj; //p aponta para um objeto do tipo D_class derivado de B_class
((D_class *)p) ->mostra_tel();
O polimorfismo em tempo de execução é obtido pelo uso de
tipos derivados e funções virtuais. Função virtual
é definida como virtual em uma class base e redefinida em uma ou mais
classes derivadas. O que torna a função virtual especial é
que quando uma é acessada usando-se um ponteiro da class base para um
objeto da class derivada, o C++ determina qual a função a chamar
no momento da execução. Uma função virtual
é declarada como tal dentro da class base precedendo-se sua
declaração com a palavra reservada virtual.
Como primeiro exemplo de função virtual temos:
clas30.cpp no FTP ou veja aqui...
clas30.cpp
A função virtual em combinação com os tipos
derivados permite ao C++ suportar polimorfismo em tempo de
execução. O polimorfismo deixa uma class generalizada
especificar as funções que serão comuns a qualquer
derivada daquela class enquanto permite a uma class derivada especificar a
implementação de alguma ou todas funções. Assim
temos o conceito de "uma interface, múltiplos métodos".
O exemplo que segue cria uma class base chamada figura, que é usada para
armazenar as dimensões de vários objetos bidimensionais e para
calcular as respectivas áreas. A função fixa_dim()
é a função membro padrão, uma vez que sua
operação será comum a todas as classes derivadas.
Entretanto exibe_area() é declarada como virtual, já que varia a
maneira como a área de cada objeto é calculada. O programa usa a
classe figura para derivar outras classes específicas.
class31.cpp no FTP ou veja aqui....
clas31.cpp
Uma função virtual pura é aquela declarada em uma class
base que não tenha definição relativa a base. Assim
qualquer tipo derivado deve definir a sua própria versão. Para
criar uma função virtual pura usa-se a forma geral,
virtual tipo nome-da-função (lista de parametros) = 0;Assim no exemplo que segue, a função exibe_area() é uma função virtual pura.
class figura { double x, y; public: void fixa_dim(double i, double j=0) { x=i; y=j; } virtual void exibe_area() = 0; // virtual pura... };
Há dois termos que são normalmente usados quando se discute
linguagens de programação orientada a objeto:
ligação precoce e ligação tardia. Em C++ referem-se
aos eventos que ocorrem no momento da compilação e no momento da
execução respectivamente. Exemplos de ligação
precoce incluem chamadas de funções padrões, chamadas de
funções sobrecarregadas, chamadas de funções
operadoras sobrecarregadas.
A ligação tardia é conseguida em C++ pelo uso da
função virtual e tipos derivados. Pode ser usada para suportar
uma interface comum enquanto permite a vários objetos que utilizam essa
interface definir suas próprias implementações.
É possível para uma class base e para uma class derivada ter uma
função construtora. Quando uma class derivada contém um
construtor, o construtor base é executado antes da class derivada. Para
função destrutora acontece o inverso, primeiro executa a
função da classe derivada e depois da classe base. Também
é possível uma class derivada ser ela própria usada como
uma class base na criação de outra class derivada. Quando isso
acontece, os construtores são executados na ordem de
derivação e os destrutores na ordem inversa.
O exemplo que segue
ilustra este conceito:
clas32.cpp no ftp ou veja aqui...
clas32.cpp
É possível especificar mais de uma class base quando se cria um
tipo derivado. Para fazer isso, use uma lista de classes que serão
herdadas separadas por vírgula. No exemplo que segue vemos que quando
uma lista de classes bases é usada, os construtores são chamados
da esquerda para a direita e os destrutores da direita para a esquerda.
clas33.cpp no ftp ou veja aqui...
clas33.cpp