polymorphism c
Rôle du polymorphisme en C ++ avec des exemples.
Le polymorphisme est l'un des quatre piliers de la programmation orientée objet. Le polymorphisme signifie avoir de nombreuses formes. Elle peut être définie comme la technique par laquelle un objet peut prendre plusieurs formes selon la situation.
En termes de programmation, on peut dire qu'un objet peut se comporter différemment dans différentes conditions.
Dans ce tutoriel, nous découvrirons en détail les types de polymorphisme, les moyens de mettre en œuvre le polymorphisme ainsi que les divers autres concepts de polymorphisme.
algorithme de tri par sélection c ++
=> Vérifiez ici pour voir de A à Z des didacticiels de formation C ++ ici.
Par exemple, une femme peut jouer de nombreux rôles dans différentes situations. Pour un enfant, elle est une mère, une femme au foyer à la maison, une travailleuse au bureau, etc. Ainsi, une femme assume des rôles différents et présente des comportements différents dans des conditions différentes. Ceci est un exemple réel de polymorphisme.
De même dans le monde de la programmation également, nous pouvons avoir un opérateur «+» qui est l'opérateur d'addition binaire qui se comporte différemment lorsque les opérandes changent. Par exemple, lorsque les deux opérandes sont numériques, il effectue une addition.
En revanche, lorsque les opérandes sont des chaînes, il agit comme un opérateur de concaténation. Ainsi, le polymorphisme, en un mot, signifie une entité prenant de nombreuses formes ou se comportant différemment dans des conditions différentes.
Ce que vous apprendrez:
- Types de polymorphisme
- Polymorphisme au moment de la compilation Vs. Polymorphisme d'exécution
- Polymorphisme au moment de la compilation
- Surcharge de fonction
- Surcharge de l'opérateur
- Conclusion
- lecture recommandée
Types de polymorphisme
Le polymorphisme est divisé en deux types.
- Polymorphisme au moment de la compilation
- Polymorphisme d'exécution
Le diagramme pour représenter cela est montré ci-dessous:
Comme le montre le diagramme ci-dessus, le polymorphisme est divisé en polymorphisme à la compilation et polymorphisme à l'exécution. Le polymorphisme au moment de la compilation est divisé en surcharge d'opérateur et surcharge de fonction. Le polymorphisme d'exécution est en outre implémenté à l'aide de fonctions virtuelles.
Le polymorphisme au moment de la compilation est également connu sous le nom de polymorphisme de liaison précoce ou de polymorphisme statique. Dans ce type de polymorphisme, la méthode de l’objet est appelée au moment de la compilation. Dans le cas du polymorphisme d’exécution, la méthode de l’objet est appelée au moment de l’exécution.
Le polymorphisme d'exécution est également connu sous le nom de polymorphisme dynamique ou de liaison tardive ou dynamique. Nous examinerons la mise en œuvre détaillée de chacune de ces techniques dans les rubriques suivantes.
Polymorphisme au moment de la compilation Vs. Polymorphisme d'exécution
Voyons ci-dessous les principales différences entre le temps de compilation et le polymorphisme d'exécution.
Polymorphisme au moment de la compilation | Polymorphisme d'exécution |
---|---|
Aussi connu sous le nom de polymorphisme statique ou de liaison précoce | Aussi connu sous le nom de polymorphisme dynamique ou liaison tardive / dynamique |
La méthode Objects est appelée au moment de la compilation | La méthode de l'objet est appelée au moment de l'exécution |
Généralement implémenté en utilisant la surcharge d'opérateur et la surcharge de fonction | Implémenté à l'aide de fonctions virtuelles et de remplacement de méthode |
La surcharge de méthode est un polymorphisme à la compilation dans lequel plusieurs méthodes peuvent avoir le même nom mais des listes de paramètres et des types différents. | Le remplacement de méthode est un polymorphisme d'exécution où plusieurs méthodes ont le même nom avec le même prototype |
Puisque les méthodes sont connues au moment de la compilation, l'exécution est plus rapide | L'exécution est plus lente car la méthode est connue à l'exécution |
Fournit moins de flexibilité pour mettre en œuvre des solutions car tout doit être connu au moment de la compilation | Beaucoup plus flexible pour mettre en œuvre des solutions complexes car les méthodes sont décidées au moment de l'exécution |
Polymorphisme au moment de la compilation
Le polymorphisme au moment de la compilation est une technique dans laquelle la méthode d’un objet est appelée au moment de la compilation.
Ce type de polymorphisme est implémenté de deux manières.
- Surcharge de fonction
- Surcharge de l'opérateur
Nous discuterons de chaque technique en détail.
Surcharge de fonction
Une fonction est dite surchargée lorsque nous avons plus d'une fonction avec le même nom mais des types de paramètres différents ou un nombre d'arguments différent.
Ainsi, une fonction peut être surchargée en fonction des types de paramètres, de l'ordre des paramètres et du nombre de paramètres.
Notez que deux fonctions ayant le même nom et la même liste de paramètres mais un type de retour différent ne sont pas une fonction surchargée et entraîneront une erreur de compilation si elles sont utilisées dans le programme.
De même, lorsque les paramètres de fonction ne diffèrent que par le pointeur et si le type de tableau est équivalent, il ne doit pas être utilisé pour la surcharge.
D'autres types comme statique et non statique, const et volatile, etc. Ou les déclarations de paramètres qui diffèrent par la présence ou l'absence de valeurs par défaut ne doivent pas non plus être utilisées pour la surcharge car elles sont équivalentes du point de vue de l'implémentation.
Par exemple,les prototypes de fonction suivants sont des fonctions surchargées.
Add(int,int); Add(int,float); Add(float,int); Add(int,int,int);
Dans les prototypes ci-dessus, on voit que l'on surcharge la fonction Add en fonction du type de paramètres, de la séquence ou de l'ordre des paramètres, du nombre de paramètres, etc.
Prenons un exemple de programmation complet pour mieux comprendre la surcharge de fonctions.
#include #include using namespace std; class Summation { public: int Add(int num1,int num2) { return num1+num2; } int Add(int num1,int num2, int num3) { return num1+num2+num3; } string Add(string s1,string s2){ return s1+s2; } }; int main(void) { Summation obj; cout< Production:
35
191
19
Bonjour le monde
Dans le programme ci-dessus, nous avons une classe Summation qui définit trois fonctions surchargées nommées Add qui prend deux arguments entiers, trois arguments entiers et deux arguments chaîne.
Dans la fonction principale, nous effectuons quatre appels de fonction qui fournissent divers paramètres. Les deux premiers appels de fonction sont simples. Dans le troisième appel de fonction à Add, nous fournissons deux valeurs à virgule flottante comme arguments.
Dans ce cas, la fonction qui correspond est int Add (int, int) car en interne, le float est converti en double puis mis en correspondance avec la fonction avec les paramètres int. Si nous avions spécifié double au lieu de float, alors nous aurions une autre fonction surchargée avec double comme paramètres.
meilleur VPN pour le streaming
Le dernier appel de fonction utilise des valeurs de chaîne comme paramètres. Dans ce cas, l'opérateur Add (+) agit comme un opérateur de concaténation et concatène les deux valeurs de chaîne pour produire une seule chaîne.
Avantages de la surcharge de fonctions
Le principal avantage de la surcharge de fonctions est qu'elle favorise la réutilisabilité du code. Nous pouvons avoir autant de fonctions que possible avec le même nom tant qu'elles sont surchargées en fonction du type d'argument, de la séquence d'arguments et du nombre d'arguments.
En faisant cela, il devient plus facile d'avoir différentes fonctions avec le même nom pour représenter le comportement de la même opération dans différentes conditions.
Si la surcharge de fonctions n'était pas présente, alors nous aurions dû écrire trop de types de fonctions différentes avec des noms différents, rendant ainsi le code illisible et difficile à adapter.
Surcharge de l'opérateur
La surcharge d'opérateurs est la technique par laquelle nous donnons une signification différente aux opérateurs existants en C ++. En d'autres termes, nous surchargons les opérateurs pour donner une signification particulière aux types de données définis par l'utilisateur en tant qu'objets.
La plupart des opérateurs en C ++ sont surchargés ou reçoivent une signification spéciale afin de pouvoir travailler sur des types de données définis par l'utilisateur. Notez que lors d'une surcharge, le fonctionnement de base des opérateurs n'est pas modifié. La surcharge donne simplement à l'opérateur une signification supplémentaire en gardant la même sémantique de base.
Bien que la plupart des opérateurs puissent être surchargés en C ++, certains opérateurs ne peuvent pas être surchargés.
Ces opérateurs sont répertoriés dans le tableau ci-dessous.
Les opérateurs Opérateur de résolution de portée (: :) Taille de sélecteur de membres (.) sélecteur de pointeur de membre (*) opérateur ternaire (? :)
Les fonctions que nous utilisons pour surcharger les opérateurs sont appelées ' Fonctions opérateur ».
Les fonctions de l'opérateur sont similaires aux fonctions normales mais avec une différence. La différence est que le nom des fonctions d'opérateur commence par le mot-clé ' opérateur ”Suivi du symbole de l'opérateur à surcharger.
La fonction opérateur est alors appelée lorsque l'opérateur correspondant est utilisé dans le programme. Ces fonctions d'opérateur peuvent être des fonctions membres ou des méthodes globales ou même une fonction amie.
La syntaxe générale de la fonction opérateur est:
return_type classname::operator op(parameter list) { //function body }
Ici, «opérateur op» est la fonction d'opérateur où l'opérateur est le mot-clé et op est l'opérateur à surcharger. Return_type est le type de valeur à renvoyer.
Voyons quelques exemples de programmation pour démontrer la surcharge de l'opérateur à l'aide des fonctions opérateur.
Exemple 1:Surcharge de l'opérateur unaire à l'aide de la fonction d'opérateur membre.
#include using namespace std; class Distance { public: int feet; // Constructor to initialize the object's value Distance(int feet) { this->feet = feet; } //operator function to overload ++ operator to perform increment on Distance obj void operator++() { feet++; } void print(){ cout << '
Incremented Feet value: ' << feet; } }; int main() { Distance d1(9); // Use (++) unary operator ++d1; d1.print(); return 0; }
Production:
Valeur incrémentée en pieds: 10
Ici, nous avons surchargé l'opérateur d'incrémentation unaire à l'aide de la fonction operator ++. Dans la fonction principale, nous utilisons cet opérateur ++ pour incrémenter l'objet de la classe Distance.
Exemple 2:Surcharge de l'opérateur binaire à l'aide de la fonction d'opérateur membre.
#include using namespace std; class Complex { int real, imag; public: Complex(int r = 0, int i =0) {real = r; imag = i;} //Operator function to overload binary + to add two complex numbers Complex operator + (Complex const &obj) { Complex c3; c3.real = real + obj.real; c3.imag = imag + obj.imag; return c3; } void print() { cout << real << ' + i' << imag << endl; } }; int main() { Complex c1(2, 5), c2(3, 7); cout<<'c1 = '; c1.print(); cout<<'c2 = '; c2.print(); cout<<'c3 = c1+c2 = '; Complex c3 = c1 + c2; // calls overloaded + operator c3.print(); }
Production:
c1 = 2 + i5
c2 = 3 + i7
c3 = c1 + c2 = 5 + i12
Nous avons utilisé ici l'exemple classique de l'addition de deux nombres complexes en utilisant la surcharge d'opérateur. Nous définissons une classe pour représenter les nombres complexes et une fonction opérateur pour surcharger + opérateur dans laquelle nous ajoutons les parties réelles et imaginaires des nombres complexes.
Dans la fonction principale, nous déclarons deux objets complexes et les ajoutons à l'aide de l'opérateur surchargé + pour obtenir le résultat souhaité.
Dans l'exemple ci-dessous, nous utiliserons la fonction friend pour ajouter deux nombres complexes afin de voir la différence d'implémentation.
#include using namespace std; class Complex { int real, imag; public: Complex(int r = 0, int i =0) {real = r; imag = i;} //friend function to overload binary + to add two complex numbers friend Complex operator +(Complex const &, Complex const &); void print() { cout << real << ' + i' << imag << endl; } }; Complex operator + (Complex const &c1, Complex const &c2) { Complex c3; c3.real = c1.real + c2.real; c3.imag = c1.imag + c2.imag; return c3; } int main() { Complex c1(2, 5), c2(3, 7); cout<<'c1 = '; c1.print(); cout<<'c2 = '; c2.print(); cout<<'c3 = c1+c2 = '; Complex c3 = c1 + c2; // calls overloaded + operator c3.print(); }
Production:
c1 = 2 + i5
c2 = 3 + i7
c3 = c1 + c2 = 5 + i12
Nous voyons que la sortie du programme est la même. La seule différence dans l'implémentation est l'utilisation de la fonction friend pour surcharger l'opérateur + au lieu d'une fonction membre dans l'implémentation précédente.
Lorsque la fonction friend est utilisée pour un opérateur binaire, nous devons spécifier explicitement les deux opérandes de la fonction. De même, lorsque l'opérateur unaire est surchargé à l'aide de la fonction friend, nous devons fournir l'opérande unique à la fonction.
bon endroit pour regarder l'anime en ligne gratuitement
Outre les fonctions d'opérateur, nous pouvons également écrire un opérateur de conversion qui est utilisé pour passer d'un type à un autre. Ces opérateurs de conversion surchargés doivent être une fonction membre de la classe.
Exemple 3:Surcharge de l'opérateur utilisant l'opérateur de conversion.
#include using namespace std; class DecFraction { int numerator, denom; public: DecFraction(int num, int denm) { numerator = num; denom = denm; } // conversion operator: converts fraction to float value and returns it operator float() const { return float(numerator) / float(denom); } }; int main() { DecFraction df(3, 5); //object of class float res_val = df; //calls conversion operator cout << 'The resultant value of given fraction (3,5)= '< Production:
La valeur résultante de la fraction donnée (3,5) = 0,6
Dans ce programme, nous avons utilisé l'opérateur de conversion pour convertir la fraction donnée en une valeur flottante. Une fois la conversion effectuée, l'opérateur de conversion renvoie la valeur résultante à l'appelant.
Dans la fonction main, lorsque nous affectons l'objet df à une variable res_val, la conversion a lieu et le résultat est stocké dans res_val.
Nous pouvons également appeler un constructeur avec un seul argument. Lorsque nous pouvons appeler un constructeur de la classe en utilisant un seul argument, cela s'appelle un ' conversion constructeur ». Le constructeur de conversion peut être utilisé pour une conversion implicite vers la classe en cours de construction.
#include using namespace std; class Point { private: int x,y; public: Point(int i=0,int j=0) {x = i;y=j;} void print() { cout<<' x = '< Production:
Point construit en utilisant un constructeur normal
x = 20 y = 30
Point construit à l'aide du constructeur de conversion
x = 10 y = 0

Ici, nous avons une classe Point qui définit un constructeur avec des valeurs par défaut. Dans la fonction principale, nous construisons un objet pt avec les coordonnées x et y. Ensuite, nous attribuons simplement à pt une valeur de 10. C'est là que le constructeur de conversion est appelé et que x reçoit une valeur de 10 tandis que y reçoit la valeur par défaut de 0.
Règles de surcharge des opérateurs
Lors de la surcharge des opérateurs, nous devons faire attention aux règles ci-dessous.
- En C ++, nous ne pouvons surcharger que les opérateurs existants. Les opérateurs nouvellement ajoutés ne peuvent pas être surchargés.
- Lorsque les opérateurs sont surchargés, nous devons nous assurer qu'au moins l'un des opérandes est du type défini par l'utilisateur.
- Pour surcharger certains opérateurs, nous pouvons également utiliser la fonction friend.
- Lorsque nous surchargons des opérateurs unaires à l'aide d'une fonction membre, cela ne prend aucun argument explicite. Il prend un argument explicite lorsque l'opérateur unaire est surchargé à l'aide de la fonction friend.
- De même, lorsque les opérateurs binaires sont surchargés à l'aide de la fonction membre, nous devons fournir un argument explicite à la fonction. Lorsque les opérateurs binaires sont surchargés à l'aide de la fonction friend, la fonction prend deux arguments.
- Il existe deux opérateurs en C ++ qui sont déjà surchargés. Ce sont «=» et «&». Par conséquent, pour copier un objet de la même classe, nous n'avons pas besoin de surcharger l'opérateur =, et nous pouvons l'utiliser directement.
Avantages de la surcharge de l'opérateur
La surcharge d'opérateurs en C ++ nous permet d'étendre la fonctionnalité des opérateurs aux types définis par l'utilisateur, y compris les objets de classe en plus des types intégrés.
En étendant la fonctionnalité d'opérateur aux types définis par l'utilisateur, nous n'avons pas besoin d'écrire du code complexe pour effectuer diverses opérations sur les types définis par l'utilisateur, mais nous pouvons le faire en une seule opération, tout comme les types intégrés.
Conclusion
Le polymorphisme au moment de la compilation fournit une fonction de surcharge principalement pour étendre la fonctionnalité du code en termes de surcharge de fonction et de surcharge d'opérateur.
Grâce à la surcharge de fonctions, nous pouvons écrire plus d'une fonction avec le même nom mais des paramètres et des types différents. Cela rend le code simple et facilement lisible. En surchargeant les opérateurs, nous pouvons étendre la fonctionnalité des opérateurs, afin de pouvoir également effectuer des opérations de base sur des types définis par l'utilisateur.
Dans notre prochain didacticiel, nous en apprendrons davantage sur le polymorphisme d'exécution en C ++.
=> Lisez la série de formations Easy C ++.
lecture recommandée
- Polymorphisme d'exécution en C ++
- Fonctions Friend en C ++
- Récursivité en C ++
- Tutoriel sur les fonctions principales de Python avec des exemples pratiques
- Un aperçu complet de C ++
- Tutoriel QTP # 21 - Comment rendre les tests QTP modulaires et réutilisables à l'aide d'actions et de bibliothèques de fonctions
- Tutoriel Unix Pipes: Pipes dans la programmation Unix
- Fonctions de bibliothèque en C ++