C++ Polymorphisme avec exemple
Qu'est-ce que le polymorphisme dans C++?
In C++, le polymorphisme amรจne une fonction membre ร se comporter 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 son de miaulement. Lorsquโune vache invoque la mรชme fonction, elle รฉmettra le son du meuh.
Mรชme si nous avons une fonction, elle se comporte diffรฉremment selon les circonstances. La fonction a plusieurs formes ; nous avons donc atteint le polymorphisme.
Types de polymorphisme
C++ prend en charge deux types de polymorphisme :
- Polymorphisme au moment de la compilation, et
- Polymorphisme d'exรฉcution.
Polymorphisme au moment de la compilation
Vous invoquez les fonctions surchargรฉes en faisant correspondre le nombre et le type d'arguments. Les informations sont prรฉsentes au moment de la compilation. Cela signifie que C++ le compilateur sรฉlectionnera la bonne fonction au moment de la compilation.
Le polymorphisme au moment de la compilation est obtenu grรขce ร la surcharge de fonctions et ร la 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 <iostream>
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;
}
Sortie :
Voici une capture d'รฉcran du code :
Code Explication:
- Incluez le fichier d'en-tรชte iostream dans notre code. Nous pourrons utiliser ses fonctions.
- Incluez l'espace de noms std dans notre code. Nous pourrons utiliser ses classes sans l'appeler.
- Crรฉez une fonction nommรฉe test qui prend un paramรจtre entier i. Le { marque le dรฉbut du corps du test fonctionnel.
- Instruction ร exรฉcuter si le test de fonction ci-dessus est invoquรฉ/appelรฉ.
- Fin du corps du test fonctionnel ci-dessus.
- Crรฉez une fonction nommรฉe test qui prend un paramรจtre float f. Le { marque le dรฉbut du corps du test fonctionnel.
- Instruction ร exรฉcuter si le test de fonction ci-dessus est invoquรฉ/appelรฉ.
- Fin du corps du test fonctionnel ci-dessus.
- 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 fonctionnel.
- Instruction ร exรฉcuter si le test de fonction ci-dessus est invoquรฉ/appelรฉ.
- Fin du corps du test fonctionnel ci-dessus.
- Appelez la fonction main(). Le { marque le dรฉbut du corps de la fonction.
- 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.
- Appelez la fonction test et passez-lui 5.5 comme valeur de l'argument. Cela invoquera la fonction de test qui accepte un argument float, c'est-ร -dire la deuxiรจme fonction de test.
- Appelez la fonction test et transmettez-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.
- Le programme doit renvoyer une valeur s'il s'exรฉcute correctement.
- La fin du corps de la fonction main().
Nous avons trois fonctions portant le mรชme nom mais des types dโarguments diffรฉrents. Nous avons atteint le polymorphisme.
OperaTor Surcharge
In Operator Surcharge, nous dรฉfinissons un nouveau sens pour un C++ opรฉrateur. 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. D'aprรจs notre dรฉfinition, lorsqu'il est placรฉ entre des entiers, il les additionne. Lorsqu'il est placรฉ entre des chaรฎnes, il les concatรจne.
Exemple 2
#include<iostream>
using 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();
}
Sortie :
Voici une capture d'รฉcran du code :
Code Explication:
- Incluez le fichier d'en-tรชte iostream dans notre programme afin d'utiliser ses fonctions.
- Incluez l'espace de noms std dans notre programme afin d'utiliser ses classes sans l'appeler.
- Crรฉez une classe nommรฉe ComplexNum. Le { marque le dรฉbut du corps de la classe.
- 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.
- Dรฉfinissez deux variables entiรจres, rรฉelles et supรฉrieures.
- Utilisez le modificateur d'accรจs public pour marquer le constructeur comme public, ce qui signifie qu'il sera accessible mรชme depuis l'extรฉrieur du classe.
- Crรฉez le constructeur de classe et initialisez les variables.
- Initialisez la valeur de la variable real.
- Initialisez la valeur de la variable over.
- Fin du corps constructeur.
- Nous devons remplacer la signification de lโopรฉrateur +.
- Crรฉez le rรฉsultat du type de donnรฉes de type ComplexNum.
- Utilisez l'opรฉrateur + avec les nombres complexes. Cette ligne ajoutera la partie rรฉelle d'un nombre ร la partie rรฉelle d'un autre nombre.
- Utilisez l'opรฉrateur + avec les nombres complexes. Cette ligne ajoutera la partie imaginaire d'un nombre ร la partie imaginaire d'un autre nombre.
- Le programme renverra la valeur du rรฉsultat variable en cas d'exรฉcution rรฉussie.
- Fin de la dรฉfinition du nouveau sens de l'opรฉrateur +, c'est-ร -dire la surcharge.
- Appelez la mรฉthode print().
- Imprimez le nouveau numรฉro complexe aprรจs ajout sur la console.
- Fin du corps de la fonction print().
- Fin du corps de la classe ComplexNum.
- Appelez la fonction main().
- 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, soit 10+3. La deuxiรจme partie de c1 sera ajoutรฉe ร la deuxiรจme partie de c, soit 2+7.
- Effectuez une opรฉration en utilisant l'opรฉrateur + surchargรฉ et en stockant le rรฉsultat dans la variable c3.
- Imprimez la valeur de la variable c3 sur la console.
- 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 grรขce au remplacement de fonctions. La fonction ร appeler/invoquรฉe 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 <iostream>
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;
}
Sortie :
Voici une capture d'รฉcran du code :
Code Explication:
- Importez le fichier d'en-tรชte iostream dans notre programme pour utiliser ses fonctions.
- Incluez l'espace de noms std dans notre programme afin d'utiliser ses classes sans l'appeler.
- Crรฉez une classe nommรฉe Mammifรจre. Le { marque le dรฉbut du corps de la classe.
- Utilisez le modificateur d'accรจs public pour dรฉfinir la fonction que nous sommes sur le point de crรฉer comme accessible publiquement. Il sera accessible depuis l'extรฉrieur de cette classe.
- Crรฉez une fonction publique nommรฉe manger. Le { marque le dรฉbut du corps de la fonction.
- Affiche l'instruction ajoutรฉe ร la fonction cout lorsque la fonction eat() est invoquรฉe.
- La fin du corps de la fonction eat().
- Fin du corps de la classe Mammifรจre.
- Crรฉez une classe nommรฉe Cow qui hรฉrite de la classe Mammal. La vache est la classe dรฉrivรฉe, tandis que les mammifรจres sont la classe de base. Le { marque le dรฉbut de cette classe.
- Utilisez le modificateur d'accรจs public pour marquer la fonction que nous sommes sur le point de crรฉer comme accessible publiquement. Il sera accessible depuis l'extรฉrieur de cette classe.
- Remplacez la fonction eat() qui a รฉtรฉ dรฉfinie dans la classe de base. Le { marque le dรฉbut du corps de la fonction.
- L'instruction ร imprimer sur la console lorsque cette fonction est invoquรฉe.
- Fin du corps de la fonction eat().
- Fin du corps de la classe Vache.
- Appelez la fonction main(). Le { marque le dรฉbut du corps de cette fonction.
- Crรฉez une instance de la classe Cow et donnez-lui le nom c.
- Appelez la fonction eat() dรฉfinie dans la classe Cow.
- Le programme doit renvoyer une valeur une fois terminรฉ.
- Fin de la fonction main().
C++ Fonction virtuelle
Une fonction virtuelle est une autre faรงon d'implรฉmenter le polymorphisme d'exรฉcution dans C++. Il s'agit d'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 fonctions virtuelles est hรฉritรฉe, la classe virtuelle redรฉfinit la fonction virtuelle en fonction de ses besoins. Par exemple:
#include <iostream>
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();
}
Sortie :
Voici une capture d'รฉcran du code :
Code Explication:
- Incluez le fichier d'en-tรชte iostream dans le code pour utiliser ses fonctions.
- Incluez l'espace de noms std dans notre code pour utiliser ses classes sans l'appeler.
- Crรฉez une classe nommรฉe ClassA.
- Utilisez le modificateur d'accรจs public pour marquer un membre de la classe comme accessible publiquement.
- Crรฉez une fonction virtuelle nommรฉe show(). Ce sera une fonction publique.
- Le texte ร imprimer lorsque le show() invoquรฉ est invoquรฉ. La fin est un C++ mot-clรฉ, qui signifie ligne de fin. Il dรฉplace le curseur de la souris vers la ligne suivante.
- Fin du corps de la fonction virtuelle show().
- Fin du corps de la classe ClassA.
- 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.
- Utilisez le modificateur d'accรจs public pour marquer un membre de la classe comme accessible publiquement.
- Redรฉfinissez la fonction virtuelle show() dรฉrivรฉe dans la classe de base.
- Le texte ร imprimer sur la console lorsque la fonction show() dรฉfinie dans la classe dรฉrivรฉe est invoquรฉe.
- Fin du corps de la fonction show().
- Fin du corps de la classe dรฉrivรฉe, ClassB.
- Appelez la fonction main(). La logique du programme doit รชtre ajoutรฉe dans son corps.
- Crรฉez une variable de pointeur nommรฉe a. Il pointe vers la classe nommรฉe ClassA.
- Crรฉez une instance de la classe nommรฉe ClassB. L'instance reรงoit le nom b.
- Affectez les valeurs stockรฉes ร lโadresse b dans la variable a.
- Invoquez la fonction show() dรฉfinie dans la classe dรฉrivรฉe. La liaison tardive a รฉtรฉ mise en ลuvre.
- Fin du corps de la fonction main().
Polymorphisme au moment de la compilation vs. Polymorphisme d'exรฉcution
Voici les principales diffรฉrences entre les deux :
| Polymorphisme ร la compilation | Polymorphisme d'exรฉcution |
|---|---|
| On l'appelle รฉgalement liaison prรฉcoce ou polymorphisme statique. | On l'appelle รฉgalement 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 une surcharge de fonctions et une surcharge d'opรฉrateurs | 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, substitution de mรฉthode. De nombreuses mรฉthodes peuvent avoir un nom similaire et le mรชme prototype. |
| Exรฉcution plus rapide puisque la dรฉcouverte des mรฉthodes se fait pendant la compilation | Exรฉcution plus lente puisque le dรฉcouvreur de mรฉthodes est effectuรฉ pendant lโexรฉcution. |
| Less la flexibilitรฉ pour la rรฉsolution de problรจmes est fournie puisque tout est connu au moment de la compilation. | Une grande flexibilitรฉ est offerte pour rรฉsoudre des problรจmes complexes puisque les mรฉthodes sont dรฉcouvertes pendant l'exรฉcution. |
Rรฉsumรฉ
- Le polymorphisme signifie avoir plusieurs 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 au moment de la compilation, la fonction ร appeler est รฉtablie au moment de la compilation.
- Dans le polymorphisme d'exรฉcution, la fonction ร appeler est รฉtablie pendant l'exรฉcution.
- Le polymorphisme au moment de 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 C++ opรฉrateurs de Python.
- Le polymorphisme d'exรฉcution est obtenu grรขce au remplacement de fonctions.
- Lors du remplacement de fonction, une classe dรฉrivรฉe donne une nouvelle dรฉfinition ร une fonction dรฉfinie dans la classe de base.







