Surcharge des fonctions en C++
La surcharge de fonctions est une fonctionnalité de C ++ dans laquelle deux fonctions ou plus peuvent avoir le même nom mais des paramètres différents.
Lorsque vous appelez une fonction ou un opérateur surchargé, le compilateur détermine la définition la plus appropriée à utiliser en comparant les types d'argument que vous avez utilisés pour appeler la fonction ou l'opérateur avec les types de paramètres spécifiés dans les définitions. Le processus de sélection de la fonction ou de l'opérateur surchargé le plus approprié est appelé résolution de surcharge.
La surcharge de fonctions peut être considérée comme un exemple de fonctionnalité de polymorphisme en C ++.
Dans ce cours, nous allons nous concentrer sur la surcharge de fonctions et dans le prochain cours, nous parlerons de la surcharge d'opérateurs
Surcharge de fonctions
La surcharge de fonctions est définie comme le processus consistant à avoir deux fonctions ou plus portant le même nom, mais de paramètres différents.
Dans la surcharge de fonction, la fonction est redéfinie en utilisant différents types d’arguments ou un nombre différent d’arguments. Ce n'est que par ces différences que le compilateur peut différencier les fonctions.
L'avantage de la surcharge de fonctions est qu'elle augmente la lisibilité du programme car il n'est pas nécessaire d'utiliser des noms différents pour la même action.
Supposons que nous voulions créer une seule fonction moyenne, pouvant gérer la moyenne de 2 nombres, 3 nombres de types différents, nous ne pouvons le faire qu'en utilisant la surcharge de la fonction
Exemple 1 :
#include <iostream> using namespace std; class Utilitaire { public: static float moyenne(int a, int b) { return (a + b) / 2.0; } static float moyenne(float a, float b) { return (a + b) / 2; } static float moyenne(int a, int b, int c) { return (a + b + c) / 3.0; } }; int main() { cout << "Moyenne (3,4) = " << Utilitaire::moyenne(3, 4) << endl; cout << "Moyenne (3,4,6) = " << Utilitaire::moyenne(3, 4, 6) << endl; cout << "Moyenne (6.4,1.25) = " << Utilitaire::moyenne(6.4f, 1.25f) << endl; return 0; }
Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant
Moyenne (3,4,6) = 4.33333
Moyenne (6.4,1.25) = 3.825
Le type de retour de toutes ces fonctions est le même mais ce n'est pas nécessaire.
Surcharge de fonction et ambiguïté
Lorsque le compilateur est incapable de décider quelle fonction doit être appelée parmi la fonction surchargée, cette situation est appelée ambiguïté.
Lorsque le compilateur affiche l'erreur d'ambiguïté, il ne lance pas le programme.
Causes d'erreur d'ambiguïté
- Conversion de type.
- Fonction avec des arguments par défaut.
- Fonction avec passage par référence.
Conversion de type
Exemple 2 :
#include <iostream> using namespace std; class Utilitaire { public: static float moyenne(int a, int b) { return (a + b) / 2.0; } static float moyenne(float a, float b) { return (a + b) / 2; } }; int main() { cout << "Moyenne (3,4) = " << Utilitaire::moyenne(3, 4) << endl; cout << "Moyenne (6.4,1.25) = " << Utilitaire::moyenne(6.4, 1.25) << endl; return 0; }
Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant
test.cpp:20:40: error: call to 'moyenne' is ambiguous cout << "Moyenne (6.4,1.25) = " << Utilitaire::moyenne(6.4, 1.25) << endl; ^~~~~~~~~~~~~~~~~~~ test.cpp:7:18: note: candidate function static float moyenne(int a, int b) ^ test.cpp:11:18: note: candidate function static float moyenne(float a, float b) ^ 1 error generated.
L'exemple ci-dessus montre une erreur "call to 'moyenne' is ambiguous". moyenne(3, 4) appelle la première fonction. moyenne(6.4, 1.25) appelle la deuxième fonction selon notre prédiction. Mais, cela ne fait référence à aucune fonction comme en C ++, toutes les constantes à virgule flottante sont traitées comme des doubles, pas comme des flottantes. Si nous remplaçons float par double ou que nous plaçons la lettre f après chaque chiffre, comme dans le premier exemple, le programme fonctionne. Par conséquent, il s’agit d’une conversion de type de float en double.
Utilitaire::moyenne(6.4f, 1.25f)
Fonction avec des arguments par défaut.
Exemple 3 :
#include <iostream> using namespace std; class Utilitaire { public: static float moyenne(int a) { return (a + 7) / 2.0; } static float moyenne(int a, int b = 2) { return (a + b) / 2.0; } }; int main() { cout << "Moyenne (3,4) = " << Utilitaire::moyenne(3, 4) << endl; cout << "Moyenne (5) = " << Utilitaire::moyenne(5) << endl; return 0; }
Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant
test test.cpp:20:33: error: call to 'moyenne' is ambiguous cout << "Moyenne (5) = " << Utilitaire::moyenne(5) << endl; ^~~~~~~~~~~~~~~~~~~ test.cpp:7:18: note: candidate function static float moyenne(int a) ^ test.cpp:11:18: note: candidate function static float moyenne(int a, int b = 2) ^ 1 error generated.
L'exemple ci-dessus montre une erreur "call to 'moyenne' is ambiguous". La fonction moyenne(int a, int b = 2)"peut être appelée de deux manières: la première consiste à appeler la fonction avec un seul argument, c'est-à-dire moyenne(5) et une autre manière à appeler la fonction avec deux arguments, c'est-à-dire , moyenne(3, 4).
La fonction moyenne(int a) est appelée avec un seul argument. Par conséquent, le compilateur n'a pas pu sélectionner entre moyenne(int a) et moyenne(int a, int b = 2).
Fonction avec passage par référence.
Exemple 4 :
#include <iostream> using namespace std; class Test { public: static void Afficher(int a) { cout << "a = " << a << endl; } static void Afficher(int &a) { cout << "a = " << a << endl; } }; int main() { int a = 2; Test::Afficher(a); return 0; }
Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant
test.cpp:20:5: error: call to 'Afficher' is ambiguous Test::Afficher(a); ^~~~~~~~~~~~~~ test.cpp:7:17: note: candidate function static void Afficher(int a) ^ test.cpp:11:17: note: candidate function static void Afficher(int &a) ^ 1 error generated.
L'exemple ci-dessus montre une erreur "call to 'Afficher' is ambiguous". La première fonction prend un argument entier et la seconde prend un paramètre de référence en tant qu'argument. Dans ce cas, le compilateur ne sait pas quelle fonction est nécessaire à l'utilisateur. comme il n'y a pas de différence syntaxique entre Afficher(int) et Afficher(int &).