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.