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.