Polymorphisme en C ++

Le mot polymorphismsignifie avoir plusieurs formes. En règle générale, le polymorphisme se produit lorsqu'il existe une hiérarchie de classes et qu'elles sont liées par héritage.

Le polymorphisme C ++ signifie qu'un appel à une fonction membre entraînera l'exécution d'une fonction différente en fonction du type d'objet qui invoque la fonction.

Prenons l'exemple suivant où une classe de base a été dérivée par deux autres 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;
}

Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant -

Parent class area :
Parent class area :

La raison de la sortie incorrecte est que l'appel de la fonction area () est défini une fois par le compilateur comme version définie dans la classe de base. C'est appeléstatic resolution de l'appel de fonction, ou static linkage- l'appel de fonction est fixé avant l'exécution du programme. Ceci est aussi parfois appeléearly binding car la fonction area () est définie lors de la compilation du programme.

Mais maintenant, faisons une légère modification dans notre programme et précédons la déclaration de area () dans la classe Shape avec le mot-clé virtual pour que ça ressemble à ça -

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;
      }
};

Après cette légère modification, lorsque l'exemple de code précédent est compilé et exécuté, il produit le résultat suivant -

Rectangle class area
Triangle class area

Cette fois, le compilateur regarde le contenu du pointeur au lieu de son type. Par conséquent, puisque les adresses des objets des classes tri et rec sont stockées sous forme *, la fonction area () respective est appelée.

Comme vous pouvez le voir, chacune des classes enfants a une implémentation distincte pour la fonction area (). C'est ainsipolymorphismest généralement utilisé. Vous avez différentes classes avec une fonction du même nom, et même les mêmes paramètres, mais avec des implémentations différentes.

Fonction virtuelle

UNE virtual function est une fonction dans une classe de base qui est déclarée à l'aide du mot-clé virtual. La définition dans une classe de base d'une fonction virtuelle, avec une autre version dans une classe dérivée, signale au compilateur que nous ne voulons pas de liaison statique pour cette fonction.

Ce que nous voulons, c'est que la sélection de la fonction à appeler à un point donné du programme soit basée sur le type d'objet pour lequel elle est appelée. Ce type d'opération est appelédynamic linkage, ou late binding.

Fonctions virtuelles pures

Il est possible que vous souhaitiez inclure une fonction virtuelle dans une classe de base afin qu'elle puisse être redéfinie dans une classe dérivée pour s'adapter aux objets de cette classe, mais qu'il n'y ait pas de définition significative que vous pourriez donner pour la fonction dans la classe de base .

Nous pouvons changer la fonction virtuelle area () dans la classe de base comme suit -

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;
};

Le = 0 indique au compilateur que la fonction n'a pas de corps et que la fonction virtuelle ci-dessus sera appelée pure virtual function.