Chapitre 6
INTRODUCTION A LA GENERICITE
 
 
Précédent Suivant
 

Introduction à la généricité
Une autre approche de programmation
* Concept apparu dès les années 70
* Ce n'est pas un concept objet
* Les principes objet ne sont pas nécessaires
* ...mais proposé par les langages objets
* C++, Java, C#
* Abstraction d'un ou plusieurs types de données
* Structures de données: vecteur, pile, file, liste chaînée...
* Algorithmes: chercher, trier, insérer, extraire...
* Générique = composant paramétré sur des types
Principe (1/2)
* Offre une nouvelle manière de factoriser le code
* Dans une fonction, les paramètres sont des valeurs
* Lors de sa définition, des valeurs sont inconnues
* int max(int a,int b)
* Au moment de l'appel, ces valeurs sont fixées
* max(5,7) ==> a = 5, b = 7
* Dans un générique, les paramètres sont des types
* Lors de sa définition, des types sont inconnus
* template <class T> T max(T a,T b)
* Au moment d'utiliser le générique, ces types sont fixés
* max<int>(5,7) ==> T = int
Principe (2/2)
* Un générique est un modèle
* Instanciation = création d'un composant à partir d'un modèle
* Instancier un générique ==> fixer le type de ses paramètres
* Spécificités en C++
* Génériques appelés "templates"
* Fonctions, classes et méthodes peuvent être génériques
* Des constantes peuvent aussi être des paramètres
* Possibilité de "spécialisation statique"
* Une nouvelle forme de polymorphisme
* Permet la spécialisation pour certains types de données
Exemples
* Algorithme de tri
* Fonctionne de la même manière sur tout type de données
* Entiers, flottants, chaînes, objets d'une classe A...
==> abstraction du type manipulé T
* Suppose une relation d'ordre sur le type T ==> opérateur <
* C++ permet de définir ("surcharger") l'opérateur pour tout type
* Type liste chaînée
* Fonctionne de la même manière sur tout type de données
==> abstraction du type manipulé T
* Suppose un test d'égalité sur le type T ==> opérateur ==
Héritage vs. généricité
* Les deux approches sont complémentaires
* Toutes les deux fournissent une forme de polymorphisme
* La généricité agit à la compilation
* L'héritage agit à l'exécution
* Contribuent toutes les deux à développer du code générique
* Toutes les deux font abstraction du type
* L'une par un processus de généralisation
* L'autre par un mécanisme de paramètre
* Avec l'héritage
* Plus de flexibilité, mais moins de sûreté
* Contrôles de type effectués à l'exécution
* Peut entraîner des ralentissements significatifs
* Avec la généricité
* Moins de flexibilité, mais plus de sûreté
* Contrôles de type effectués à la compilation
* Moins de ralentissement (voire aucun) à l'exécution
Syntaxe
* Mot-clé "template"
* Suivi d'une liste de paramètres
* Liste délimitée par "<" et ">"
* Paramètres séparés par une virgule
* Précède un composant générique
* Fonction, classe ou méthode
* Définit des paramètres
* Soit des types: typename T
* Soit des constantes: int N
Fonctions génériques
* Définition d'une fonction générique
template <typename T>
const T & min(const T & a,const T & b) {
if (a < b) return a;
return b;
}
* Appel à une fonction générique (instanciation)
int i,j;
...
int k = min<int>(i,j);
* Instanciation ==> fixer les types paramétrés
* Suppose l'opérateur "<" sur le type paramétré T
* S'il n'existe pas ==> erreur de compilation
* Possibilité de le définir ==> "surcharge" opérateur
Polymorphisme statique
* Il est possible d'omettre les types paramétrés à l'instanciation
* Le compilateur peut déduire ces types
* A condition qu'il dispose des informations nécessaires
* Même mécanisme de déduction que la surcharge de nom
* Il s'agit d'une forme de polymorphisme statique
* Exemple
* int i,j; ... min(i,j); ==> instanciation de " min<int>"
* float a,b; ... min(a,b); ==> instanciation de " min<float>"
* Le compilateur peut effectuer des conversions implicites
si les types ne correspondent pas exactement
Classes génériques
* Définition d'une classe générique
template <typename T,int N> class Pile {
private:
T elements[N];
int sommet;
public:
Pile(void);
void ajouter(const T &);
T retirer(void);
};
* Instanciation d'une classe générique
* Pile<int,256> p;
STL: Standard Template Library
* Bibliothèque standard du C++ basée sur les génériques
* Fournit des conteneurs et des algorithmes génériques
* Séquences élémentaires: vector, list, deque
* Adaptations des séquences: stack, queue, priority_queue
* Conteneurs associatifs: map, multimap, set, multiset
* Algorithmes: find, sort, replace...
* Normalisée en 1998
* Avant: STL = Standard Template Library
* Après: Standard C++ Library