Fabrication industrielle
Internet des objets industriel | Matériaux industriels | Entretien et réparation d'équipement | Programmation industrielle |
home  MfgRobots >> Fabrication industrielle >  >> Industrial programming >> Langue C

Comprendre le polymorphisme en C++ : Guide pratique

Le mot polymorphisme signifie avoir plusieurs formes. Typiquement, le polymorphisme se produit lorsqu'il y a une hiérarchie de classes et qu'elles sont liées par héritage.

Le polymorphisme en C++ signifie qu'un appel à une fonction membre fera exécuter une fonction différente selon le type d'objet qui invoque la fonction.

Considérons 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 << "Aire classe parente :" << endl;
        return 0;
    }
};

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

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

// Fonction principale pour le programme
int main() {
    Shape *shape;
    Rectangle rec(10, 7);
    Triangle tri(10, 5);
    // stocker l'adresse de Rectangle
    shape = &rec;
    // appeler l'aire du rectangle.
    shape->area();
    // stocker l'adresse du Triangle
    shape = &tri;
    // appeler l'aire du triangle.
    shape->area();
    return 0;
}

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

Aire classe parente :
Aire classe parente :

La raison de la sortie incorrecte est que l'appel de la fonction area() est fixé une fois par le compilateur comme la version définie dans la classe de base. Cela s'appelle la résolution statique de l'appel de fonction, ou liaison statique - l'appel de fonction est fixé avant l'exécution du programme. C'est aussi parfois appelé liaison précoce (early binding) car la fonction area() est fixée pendant 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 qu'elle ressemble à ceci :

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

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

Aire classe Rectangle
Aire classe Triangle

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

Comme vous pouvez le voir, chacune des classes filles a une implémentation séparée pour la fonction area(). C'est ainsi que le polymorphisme est 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 fonction virtuelle est une fonction dans une classe de base qui est déclarée en utilisant le mot-clé virtual. Définir dans une classe de base 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 à tout moment du programme soit basée sur le type d'objet pour lequel elle est appelée. Ce type d'opération est appelé liaison dynamique (dynamic linkage) ou liaison tardive (late binding).

Fonctions virtuelles pures

Il est possible que vous vouliez inclure une fonction virtuelle dans une classe de base pour qu'elle puisse être redéfinie dans une classe dérivée pour convenir aux objets de cette classe, mais qu'il n'y ait pas de définition significative que vous puissiez 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;
    }
    // fonction virtuelle pure
    virtual int area() = 0;
};

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

Langue C

  1. Maîtriser les opérateurs C++ : Guide complet avec exemples pratiques
  2. Comment passer des tableaux aux fonctions en C++ : Guide pratique
  3. Classes et objets C++ : Guide pratique de la programmation orientée objet
  4. Fonctions amies et classes amies en C++ : Maîtriser le contrôle d'accès
  5. Maîtriser les templates de classe en C++ : Guide pratique
  6. Surcharge d'opérateurs en C++ : Guide pratique avec exemples de code
  7. Comprendre les classes de stockage en C++ : Portée, durée de vie et utilisation
  8. Maîtriser la surcharge en C++ : Fonctions et opérateurs expliqués
  9. Maîtriser l'abstraction de données en C++ : Simplifier la conception par séparation interface-implémentation