Polimorfismo em C ++

A palavra polymorphismsignifica ter muitas formas. Normalmente, o polimorfismo ocorre quando há uma hierarquia de classes e elas estão relacionadas por herança.

O polimorfismo C ++ significa que uma chamada para uma função de membro fará com que uma função diferente seja executada, dependendo do tipo de objeto que invoca a função.

Considere o seguinte exemplo, onde uma classe base foi derivada por outras duas classes -

#include <iostream> 
using namespace std;
 
class Shape {
   protected:
      int width, height;
      
   public:
      Shape( int a = 0, int b = 0){
         width = a;
         height = b;
      }
      int area() {
         cout << "Parent class area :" <<endl;
         return 0;
      }
};
class Rectangle: public Shape {
   public:
      Rectangle( int a = 0, int b = 0):Shape(a, b) { }
      
      int area () { 
         cout << "Rectangle class area :" <<endl;
         return (width * height); 
      }
};

class Triangle: public Shape {
   public:
      Triangle( int a = 0, int b = 0):Shape(a, b) { }
      
      int area () { 
         cout << "Triangle class area :" <<endl;
         return (width * height / 2); 
      }
};

// Main function for the program
int main() {
   Shape *shape;
   Rectangle rec(10,7);
   Triangle  tri(10,5);

   // store the address of Rectangle
   shape = &rec;
   
   // call rectangle area.
   shape->area();

   // store the address of Triangle
   shape = &tri;
   
   // call triangle area.
   shape->area();
   
   return 0;
}

Quando o código acima é compilado e executado, ele produz o seguinte resultado -

Parent class area :
Parent class area :

O motivo da saída incorreta é que a chamada da função area () está sendo definida uma vez pelo compilador como a versão definida na classe base. Isso é chamadostatic resolution da chamada de função, ou static linkage- a chamada de função é corrigida antes de o programa ser executado. Isso também é chamado às vezesearly binding porque a função area () é definida durante a compilação do programa.

Mas agora, vamos fazer uma pequena modificação em nosso programa e preceder a declaração de area () na classe Shape com a palavra-chave virtual para que se pareça com isto -

class Shape {
   protected:
      int width, height;
      
   public:
      Shape( int a = 0, int b = 0) {
         width = a;
         height = b;
      }
      virtual int area() {
         cout << "Parent class area :" <<endl;
         return 0;
      }
};

Após esta pequena modificação, quando o código de exemplo anterior é compilado e executado, ele produz o seguinte resultado -

Rectangle class area
Triangle class area

Desta vez, o compilador examina o conteúdo do ponteiro em vez de seu tipo. Conseqüentemente, como os endereços dos objetos das classes tri e rec são armazenados na forma *, a função area () respectiva é chamada.

Como você pode ver, cada uma das classes filhas possui uma implementação separada para a função area (). É assimpolymorphismé geralmente usado. Você tem classes diferentes com uma função de mesmo nome e até os mesmos parâmetros, mas com implementações diferentes.

Função Virtual

UMA virtual function é uma função em uma classe base que é declarada usando a palavra-chave virtual. Definir em uma classe base uma função virtual, com outra versão em uma classe derivada, sinaliza ao compilador que não queremos ligação estática para esta função.

O que queremos é que a seleção da função a ser chamada em qualquer ponto do programa seja baseada no tipo de objeto para o qual é chamada. Este tipo de operação é conhecido comodynamic linkage, ou late binding.

Funções virtuais puras

É possível que você queira incluir uma função virtual em uma classe base para que ela possa ser redefinida em uma classe derivada para se adequar aos objetos dessa classe, mas que não haja uma definição significativa que você possa dar para a função na classe base .

Podemos alterar a área de função virtual () na classe base para o seguinte -

class Shape {
   protected:
      int width, height;

   public:
      Shape(int a = 0, int b = 0) {
         width = a;
         height = b;
      }
      
      // pure virtual function
      virtual int area() = 0;
};

O = 0 diz ao compilador que a função não tem corpo e a função virtual acima será chamada pure virtual function.