Polymorphisme C ++ avec exemple

Table des matières:

Anonim

Qu'est-ce que le polymorphisme en C ++?

En C ++, le polymorphisme fait qu'une fonction membre se comporte différemment en fonction de l'objet qui l'appelle / l'invoque. Le polymorphisme est un mot grec qui signifie avoir plusieurs formes. Cela se produit lorsque vous avez une hiérarchie de classes liées par héritage.

Par exemple, supposons que nous ayons la fonction makeSound (). Lorsqu'un chat appelle cette fonction, il produira le miaulement. Lorsqu'une vache invoque la même fonction, elle émettra le son moow.

Bien que nous ayons une fonction, elle se comporte différemment selon les circonstances. La fonction a de nombreuses formes; par conséquent, nous avons atteint le polymorphisme.

Dans ce didacticiel C ++, vous apprendrez:

  • Qu'est-ce que le polymorphisme?
  • Types de polymorphisme
  • Polymorphisme au moment de la compilation
  • Surcharge de fonction
  • Surcharge de l'opérateur
  • Polymorphisme d'exécution
  • Remplacement de fonction
  • Fonction virtuelle C ++
  • Polymorphisme à la compilation Vs. Polymorphisme d'exécution

Types de polymorphisme

C ++ prend en charge deux types de polymorphisme:

  • Polymorphisme à la compilation, et
  • Polymorphisme d'exécution.

Polymorphisme au moment de la compilation

Vous appelez les fonctions surchargées en faisant correspondre le nombre et le type d'arguments. Les informations sont présentes lors de la compilation. Cela signifie que le compilateur C ++ sélectionnera la bonne fonction au moment de la compilation.

Le polymorphisme à la compilation est obtenu par surcharge de fonctions et surcharge d'opérateurs.

Surcharge de fonction

La surcharge de fonctions se produit lorsque nous avons de nombreuses fonctions avec des noms similaires mais des arguments différents. Les arguments peuvent différer en termes de nombre ou de type.

Exemple 1:

#include using namespace std;void test(int i) {cout << " The int is " << i << endl;}void test(double f) {cout << " The float is " << f << endl;}void test(char const *ch) {cout << " The char* is " << ch << endl;}int main() {test(5);test(5.5);test("five");return 0;}

Production:

Voici une capture d'écran du code:

Explication du code:

  1. Incluez le fichier d'en-tête iostream dans notre code. Nous pourrons utiliser ses fonctions.
  2. Incluez l'espace de noms std dans notre code. Nous pourrons utiliser ses classes sans l'appeler.
  3. Créez une fonction nommée test qui prend un paramètre entier i. Le {marque le début du corps du test de fonction.
  4. Instruction à exécuter si le test de fonction ci-dessus est invoqué / appelé.
  5. Fin du corps du test de fonctionnement ci-dessus.
  6. Créez une fonction nommée test qui prend un paramètre float f. Le {marque le début du corps du test de fonction.
  7. Instruction à exécuter si le test de fonction ci-dessus est invoqué / appelé.
  8. Fin du corps du test de fonctionnement ci-dessus.
  9. Créez une fonction nommée test qui prend un paramètre de caractère ch. Le {marque le début du corps du test de fonction.
  10. Instruction à exécuter si le test de fonction ci-dessus est invoqué / appelé.
  11. Fin du corps du test de fonctionnement ci-dessus.
  12. Appelez la fonction main (). Le {marque le début du corps de la fonction.
  13. Appelez la fonction test et passez-lui 5 comme valeur de l'argument. Cela appelle la fonction de test qui accepte un argument entier, c'est-à-dire la première fonction de test.
  14. Appelez la fonction test et passez-lui 5,5 comme valeur de l'argument. Cela invoquera la fonction de test qui accepte un argument flottant, c'est-à-dire la deuxième fonction de test.
  15. Appelez la fonction test et passez-lui cinq comme valeur de l'argument. Cela invoquera la fonction de test qui accepte un argument de caractère, c'est-à-dire la troisième fonction de test.
  16. Le programme doit renvoyer une valeur s'il s'exécute avec succès.
  17. La fin du corps de la fonction main ().

Nous avons trois fonctions avec le même nom mais des types d'arguments différents. Nous avons atteint le polymorphisme.

Surcharge de l'opérateur

Dans la surcharge d'opérateurs, nous définissons une nouvelle signification pour un opérateur C ++. Cela modifie également le fonctionnement de l'opérateur. Par exemple, nous pouvons définir l'opérateur + pour concaténer deux chaînes. Nous le connaissons comme l'opérateur d'addition pour ajouter des valeurs numériques. Après notre définition, lorsqu'il est placé entre des entiers, il les ajoutera. Lorsqu'il est placé entre les chaînes, il les concaténera.

Exemple 2:

#includeusing namespace std;class ComplexNum {private:int real, over;public:ComplexNum(int rl = 0, int ov = 0) {real = rl;over = ov;}ComplexNum operator + (ComplexNum const &obj) {ComplexNum result;result.real = real + obj.real;result.over = over + obj.over;return result;}void print() {cout << real << " + i" << over << endl;}};int main(){ComplexNum c1(10, 2), c2(3, 7);ComplexNum c3 = c1+c2;c3.print();}

Production:

Voici une capture d'écran du code:

Explication du code:

  1. Incluez le fichier d'en-tête iostream dans notre programme afin d'utiliser ses fonctions.
  2. Incluez l'espace de noms std dans notre programme afin d'utiliser ses classes sans l'appeler.
  3. Créez une classe nommée ComplexNum. Le {marque le début du corps de la classe.
  4. Utilisez le modificateur d'accès privé pour marquer les variables comme privées, ce qui signifie qu'elles ne sont accessibles qu'à partir de la classe.
  5. Définissez deux variables entières, réelles et supérieures.
  6. Utilisez le modificateur d'accès public pour marquer le constructeur comme public, ce qui signifie qu'il sera accessible même de l'extérieur de la classe.
  7. Créez le constructeur de classe et initialisez les variables.
  8. Initialisez la valeur de la variable real.
  9. Initialisez la valeur de la variable over.
  10. Fin du corps du constructeur.
  11. Nous devons remplacer la signification de l'opérateur +.
  12. Créez le résultat du type de données de type ComplexNum.
  13. Utilisez l'opérateur + avec des nombres complexes. Cette ligne ajoutera la partie réelle d'un nombre à la partie réelle d'un autre nombre.
  14. Utilisez l'opérateur + avec des nombres complexes. Cette ligne ajoutera la partie imaginaire d'un nombre à la partie imaginaire d'un autre nombre.
  15. Le programme renverra la valeur du résultat de la variable après une exécution réussie.
  16. Fin de la définition de la nouvelle signification de l'opérateur +, c'est-à-dire surcharge.
  17. Appelez la méthode print ().
  18. Imprimez le nouveau nombre complexe après l'ajout sur la console.
  19. Fin du corps de la fonction print ().
  20. Fin du corps de la classe ComplexNum.
  21. Appelez la fonction main ().
  22. Transmettez les valeurs des pièces réelles et complexes à ajouter. La première partie de c1 sera ajoutée à la première partie de c2, c'est-à-dire 10 + 3. La deuxième partie de c1 sera ajoutée à la deuxième partie de c, c'est-à-dire 2 + 7.
  23. Effectuez une opération en utilisant l'opérateur surchargé + et en stockant le résultat dans la variable c3.
  24. Imprimez la valeur de la variable c3 sur la console.
  25. Fin du corps de la fonction main ().

Polymorphisme d'exécution

Cela se produit lorsque la méthode d'un objet est invoquée / appelée pendant l'exécution plutôt que pendant la compilation. Le polymorphisme d'exécution est obtenu par le remplacement de fonction. La fonction à appeler / invoquer est établie pendant l'exécution.

Remplacement de fonction

Le remplacement de fonction se produit lorsqu'une fonction de la classe de base reçoit une nouvelle définition dans une classe dérivée. À ce moment-là, nous pouvons dire que la fonction de base a été remplacée.

Par exemple:

#include using namespace std;class Mammal {public:void eat() {cout << "Mammals eat… ";}};class Cow: public Mammal {public:void eat() {cout << "Cows eat grass… ";}};int main(void) {Cow c = Cow();c.eat();return 0;}

Production:

Voici une capture d'écran du code:

Explication du code:

  1. Importez le fichier d'en-tête iostream dans notre programme pour utiliser ses fonctions.
  2. Incluez l'espace de noms std dans notre programme afin d'utiliser ses classes sans l'appeler.
  3. Créez une classe nommée Mammal. Le {marque le début du corps de la classe.
  4. Utilisez le modificateur d'accès public pour définir la fonction que nous sommes sur le point de créer comme accessible au public. Il sera accessible de l'extérieur de cette classe.
  5. Créez une fonction publique nommée eat. Le {marque le début du corps de la fonction.
  6. Affiche l'instruction ajoutée à la fonction cout lorsque la fonction eat () est appelée.
  7. La fin du corps de la fonction mange ().
  8. Fin du corps de la classe Mammifère.
  9. Créez une classe nommée Cow qui hérite de la classe Mammal. Cow est la classe dérivée, tandis que Mammal est la classe de base. Le {marque le début de ce cours.
  10. Utilisez le modificateur d'accès public pour marquer la fonction que nous sommes sur le point de créer comme accessible au public. Il sera accessible de l'extérieur de cette classe.
  11. Remplacez la fonction eat () qui a été définie dans la classe de base. Le {marque le début du corps de la fonction.
  12. L'instruction à imprimer sur la console lorsque cette fonction est appelée.
  13. Fin du corps de la fonction eat ().
  14. Fin du corps de la classe Vache.
  15. Appelez la fonction main (). Le {marque le début du corps de cette fonction.
  16. Créez une instance de la classe Cow et donnez-lui le nom c.
  17. Appelez la fonction eat () définie dans la classe Cow.
  18. Le programme doit renvoyer une valeur une fois terminé.
  19. Fin de la fonction main ().

Fonction virtuelle C ++

Une fonction virtuelle est une autre façon d'implémenter le polymorphisme d'exécution en C ++. C'est une fonction spéciale définie dans une classe de base et redéfinie dans la classe dérivée. Pour déclarer une fonction virtuelle, vous devez utiliser le mot clé virtual. Le mot-clé doit précéder la déclaration de la fonction dans la classe de base.

Si une classe de fonction virtuelle est héritée, la classe virtuelle redéfinit la fonction virtuelle en fonction de ses besoins. Par exemple:

#include using namespace std;class ClassA {public:virtual void show() {cout << "The show() function in base class invoked… " << endl;}};class ClassB :public ClassA {public:void show() {cout << "The show() function in derived class invoked… ";}};int main() {ClassA* a;ClassB b;a = &b;a->show();}

Production:

Voici une capture d'écran du code:

Explication du code:

  1. Incluez le fichier d'en-tête iostream dans le code pour utiliser ses fonctions.
  2. Incluez l'espace de noms std dans notre code pour utiliser ses classes sans l'appeler.
  3. Créez une classe nommée ClassA.
  4. Utilisez le modificateur d'accès public pour marquer un membre de classe comme accessible au public.
  5. Créez une fonction virtuelle nommée show (). Ce sera une fonction publique.
  6. Le texte à imprimer lorsque show () est appelé est appelé. Le endl est un mot-clé C ++, ce qui signifie la ligne de fin. Il déplace le curseur de la souris sur la ligne suivante.
  7. Fin du corps de la fonction virtuelle show ().
  8. Fin du corps de la classe ClassA.
  9. Création d'une nouvelle classe nommée ClassB qui hérite de la classe ClassA. ClassA devient la classe de base tandis que ClassB devient la classe dérivée.
  10. Utilisez le modificateur d'accès public pour marquer un membre de classe comme accessible au public.
  11. Redéfinissez la fonction virtuelle show () dérivée de la classe de base.
  12. Le texte à imprimer sur la console lorsque la fonction show () définie dans la classe dérivée est appelée.
  13. Fin du corps de la fonction show ().
  14. Fin du corps de la classe dérivée, ClassB.
  15. Appelez la fonction main (). La logique du programme doit être ajoutée dans son corps.
  16. Créez une variable de pointeur nommée a. Il pointe vers la classe nommée ClassA.
  17. Créez une instance de la classe nommée ClassB. L'instance reçoit le nom b.
  18. Affectez les valeurs stockées à l'adresse b dans la variable a.
  19. Appelez la fonction show () définie dans la classe dérivée. La liaison tardive a été mise en œuvre.
  20. Fin du corps de la fonction main ().

Polymorphisme à la compilation Vs. Polymorphisme d'exécution

Voici les principales différences entre les deux:

Polymorphisme à la compilation Polymorphisme d'exécution
C'est aussi appelé liaison précoce ou polymorphisme statique C'est aussi appelé liaison tardive / dynamique ou polymorphisme dynamique
La méthode est appelée / invoquée pendant la compilation La méthode est appelée / invoquée pendant l'exécution
Implémenté via la surcharge de fonctions et la surcharge de l'opérateur Implémenté via le remplacement de méthode et les fonctions virtuelles
Exemple, surcharge de méthode. De nombreuses méthodes peuvent avoir des noms similaires mais un nombre ou des types d'arguments différents Exemple, remplacement de méthode. De nombreuses méthodes peuvent avoir un nom similaire et le même prototype.
Exécution plus rapide car la découverte des méthodes est effectuée pendant la compilation Exécution plus lente car le découvreur de méthode est effectué pendant l'exécution.
Moins de flexibilité pour la résolution de problèmes est fournie car tout est connu pendant la compilation. Une grande flexibilité est fournie pour résoudre des problèmes complexes puisque les méthodes sont découvertes pendant l'exécution.

Résumé:

  • Le polymorphisme signifie avoir de nombreuses formes.
  • Cela se produit lorsqu'il existe une hiérarchie de classes liées par héritage.
  • Avec le polymorphisme, une fonction peut se comporter différemment en fonction de l'objet qui l'invoque / l'appelle.
  • Dans le polymorphisme à la compilation, la fonction à appeler est établie pendant la compilation.
  • Dans le polymorphisme d'exécution, la fonction à appeler est établie pendant l'exécution.
  • Le polymorphisme à la compilation est déterminé par la surcharge de fonctions et la surcharge d'opérateurs.
  • Dans la surcharge de fonctions, il existe de nombreuses fonctions avec des noms similaires mais des arguments différents.
  • Les paramètres peuvent différer en nombre ou en type.
  • Dans la surcharge d'opérateurs, une nouvelle signification est définie pour les opérateurs C ++.
  • Le polymorphisme d'exécution est obtenu par le remplacement de fonction.
  • Dans le remplacement de fonction, une classe dérivée donne une nouvelle définition à une fonction définie dans la classe de base.