Digressions : surcharge, templates, espaces de noms, …#
Nous allons maintenant faire quelques digressions, pour pointer vers des fonctionnalités de C++ que nous avons utilisées sans explication jusqu’ici, et dont l’usage simple est naturel et potentiellement utile dès maintenant.
Surcharge de fonctions ♣#
using namespace std;
Exemple : la fonction monMax
#
Nous avons vu maintes fois la fonction max
sur les entiers :
int monMax(int a, int b) {
if ( a < b )
return b;
else
return a;
}
monMax(1,3)
On remarquera que le code est générique : on peut par exemple calculer de même le maximum de deux nombres réels :
double monMax(double a, double b) {
if ( a < b)
return b;
else
return a;
}
monMax(1.0, 3.5)
ou même de deux chaînes de caractères :
string monMax(string a, string b) {
if ( a < b)
return b;
else
return a;
}
monMax("toto", "alfred")
Vous remarquerez que l’on a utilisé le même nom de fonction, et que
C++
a appelé automatiquement la bonne version.
Il serait de même possible d’utiliser le même nom de fonction pour le max à trois arguments (et plus!) :
int monMax(int a, int b, int c) {
return monMax(monMax(a, b), c);
}
monMax(2,4,3)
Mais attention aux ambiguïtés:
monMax(3, 4.5)
Surcharge de fonction : résumé#
En C++, on peut avoir plusieurs fonctions avec le même nom et des signatures différentes
Idem en Java, mais pas en C ou en Python par exemple!
Il est recommandé que toutes les fonctions ayant le même nom aient la même sémantique
Digression : templates ♣#
L’exemple précédent n’est pas satisfaisant : on a dû implanter la
fonction monMax
pour chaque type sur lequel on peut faire une
comparaison, en dupliquant le même code.
Correctif : les templates pour écrire du code générique
La fonction monMax
suivante est valide pour tout type sur lequel on
peut faire des comparaisons :
template<class T>
T monMax(T a,T b) {
if ( a < b )
return b;
else
return a;
}
monMax(1,3)
monMax(string("toot"), string("alfred"))
monMax(1.4, 0.5)
monMax(8.0, 4)
Les détails seront pour un autre cours!
Digression : espaces de noms ♣#
Problème :
Des milliers de développeurs écrivent des bibliothèques, bibliothèques qui sont par la suite combinées entre elles de multiples façons non anticipées à l’origine. Comment s’assurer qu’il n’y a pas de conflit entre deux fonctions portant le même nom et la même signature dans deux bibliothèques différentes?
Solution :
Isoler chaque bibliothèque dans un espace de noms.
Exemple :
La bibliothèque standard C++ utilise l’espace de nom std
. Ainsi,
dans le programme suivant, il faudrait en principe mettre std
devant cout
, et endl
:
#include <iostream>
int main() {
std::cout << "Bonjour!" << std::endl;
return 0;
}
Notre incantation magique :
using namespace std;
dit simplement de définir des raccourcis pour rendre accessible
directement tout ce qui est défini dans l’espace de nom std
.
Vous verrez plus tard comment créer vos propres espaces de noms.