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 explications jusqu’ici, et dont l’usage est naturel et potentiellement utile dès maintenant.
Surcharge de fonctions ♣#
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 :
using namespace std;
string monMax(string a, string b) {
if ( a < b)
return b;
else
return a;
}
monMax("toto", "alfred")
Indication
Observation
Nous avons utilisé chaque fois le même nom de fonction et
C++
a appelé automatiquement la bonne version.
Indication
Remarque 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)
Attention
Attention aux ambiguïtés
monMax(3, 4.5)
Définition : Surcharge de fonction
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!
Indication
Bonne pratique Il est recommandé que toutes les fonctions ayant le même nom aient la même sémantique
Digression : templates ♣#
Avertissement
Problème
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.
Indication
Solution 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<typename T>
T monMax(T a,T b) {
if ( a < b )
return b;
else
return a;
}
monMax(1,3)
using namespace std;
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 ♣#
Avertissement
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?
Indication
Solution Isoler chaque bibliothèque dans un espace de noms (namespace)
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;
}
Indication
Explication 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.