SlideShare une entreprise Scribd logo
1  sur  31
Télécharger pour lire hors ligne
Programmation Orientée Objet en C++
      10ème Partie: Classes Génériques



               Fabio Hernandez
             Fabio.Hernandez@in2p3.fr
Vue d'Ensemble
   Notions de base
   Types, variables, opérateurs
   Contrôle d'exécution
   Fonctions
   Mémoire dynamique
   Qualité du logiciel
   Evolution du modèle objet
   Objets et classes
   Fonctions membres
   Classes génériques
   Héritage
   Polymorphisme
   Héritage multiple
   Entrée/sortie


POO en C++: Classes Génériques         314        © 1997-2003 Fabio HERNANDEZ
Table des Matières

   Motivation
   Déclaration d'une classe générique
   Utilisation
   Implémentation des fonctions membres
   Considérations particulières
   Fonctions génériques
   Contraintes
   Coût vs. Bénéfice
   Résumé




POO en C++: Classes Génériques           315          © 1997-2003 Fabio HERNANDEZ
Motivation

   Nous avons étudié les facilités offertes par C++ pour créer des
   classes permettant de définir des conteneurs d'objets d'un
   même type
   Un conteneur est un objet qui agit sur une collection de zéro ou
   plusieurs objets d'une classe particulière
   Les classes List et Queue et les tableaux sont des exemples
   des classes conteneurs
   Le type des objets contenus dans un objet de la classe List ou
   de la classe Queue est float
   Les services de ces classes (append, prepend, insert,
   remove,...) ne dépendent pas du type des objets qu'elles
   contiennent

POO en C++: Classes Génériques       316         © 1997-2003 Fabio HERNANDEZ
Motivation (suite)

   Supposons que nous voulons créer une List d'objets de type
   char
   Une possible solution consiste à dupliquer le code déjà écrit
   pour la classe List en faisant les modifications pour que les
   objets contenus soient de type char et pas float
         il faudrait aussi renommer les classes (FloatList, CharList,...)
         cette solution pose des problèmes pour la maintenance du code
   Une autre possible solution est d'utiliser les facilités de
   définition de macros du pré-processeur pour générer le code
   nécessaire sur demande du programmeur
         problèmes de maintenance
         particulièrement inélégant


POO en C++: Classes Génériques          317                © 1997-2003 Fabio HERNANDEZ
Motivation (suite)

   C++ fournit un mécanisme permettant de définir des classes (et
   des fonctions) génériques (paramétrables)
   L'idée est d'écrire des "moules" permettant de construire
   d'autres classes
         particulièrement utile pour les conteneurs
         le paramètre de la classe correspond au type des objets contenus
   En C++ cette facilité est connue sous le nom de template
   Nous allons étudier à nouveau la classe List et la modifier de
   façon à ce qu'elle devienne générique




POO en C++: Classes Génériques          318               © 1997-2003 Fabio HERNANDEZ
Contrôle d'Avancement

   Motivation
   Déclaration d'une classe générique
   Utilisation
   Implémentation des fonctions membres
   Considérations particulières
   Fonctions génériques
   Contraintes
   Coût vs. Bénéfice
   Résumé




POO en C++: Classes Génériques        319        © 1997-2003 Fabio HERNANDEZ
Déclaration
           #if !defined(LIST_H_INCLUDED)
           #define LIST_H_INCLUDED
                                                Item est le
           template <class Item>                paramètre de
           class List {                        la classe List
           public:
              // Constructors/Destructor
              List();
              List(int initialCapacity);
              List(const List& aList);
              ~List();

                // Modifiers
                bool append(Item anItem);
                bool prepend(Item anItem);
                bool insert(Item anItem, int position);
                bool remove(Item anItem);
POO en C++: Classes Génériques       320               © 1997-2003 Fabio HERNANDEZ
Déclaration (suite)

                bool      removeAll(Item anItem);
                bool      replace(int position, Item anItem);
                bool      replaceAll(Item item1, Item item2);
                void      clear();

                // Selectors
                int length() const;
                int occurrences(Item anItem) const;
                int position(Item anItem) const;
                Item itemAt(int position) const;
                Item first() const;
                Item last() const;
                bool isEqual(const List& aList) const;
                bool isEmpty() const;


POO en C++: Classes Génériques           321            © 1997-2003 Fabio HERNANDEZ
Déclaration (suite)

           private:
              // Data members
              Item* data_;
              int capacity_;
              int length_;

                // Help functions
                void resize();
           };

           #endif // LIST_H_INCLUDED




POO en C++: Classes Génériques           322           © 1997-2003 Fabio HERNANDEZ
Contrôle d'Avancement

   Motivation
   Déclaration d'une classe générique
   Utilisation
   Implémentation des fonctions membres
   Considérations particulières
   Fonctions génériques
   Contraintes
   Coût vs. Bénéfice
   Résumé




POO en C++: Classes Génériques        323        © 1997-2003 Fabio HERNANDEZ
Utilisation

   Pour utiliser (créer une instance d') une classe générique il faut
   fournir les paramètres nécessaires
   Fichier main.cpp
           #include "List.h"
           void main() {                       Création d’une
              List<char> alphabet;         instance de la classe
              alphabet.append('z');       générique avec le type
              alphabet.prepend('a');       primitif char comme
                                                paramètre
              if (alphabet.isEmpty())
                 ...
              cout << "Length = " << alphabet.length() << endl;
              ...
           }

POO en C++: Classes Génériques       324          © 1997-2003 Fabio HERNANDEZ
Utilisation (suite)

   De façon similaire pour les listes des autres types primitifs
           List<float> hitList;
           List<int> counterList;
           ...
   On peut aussi créer des instances des classes génériques avec
   comme paramètre d'autres classes
           #include "Point.h"
           #include "List.h"

           List<Point> vertexList; // A List of Point objects




POO en C++: Classes Génériques           325           © 1997-2003 Fabio HERNANDEZ
Utilisation (suite)

   Notez que les instances des classes génériques sont
   complètement identifiées par le nom de la classe et ses
   paramètres
           List<int> counterList;
           List<char> alphabet;
           ...
           // COMPILATION ERROR: 'counterList' and
           // 'alphabet' are two objets of a different class
           if (counterList.isEqual(alphabet))
              cout << "They are equal" << endl;




POO en C++: Classes Génériques           326           © 1997-2003 Fabio HERNANDEZ
Utilisation (suite)

   Afin de faciliter l'écriture, on peut définir des synonymes
           #include "List.h"
                                                   Définition d'un
           typedef List<char> CharList;           synonyme d'une
           ...                                         classe
                                                     générique
           CharList alphabet;
           alphabet.clear();
           for(char letter='a'; letter <= 'z'; ++letter)
              alphabet.append(letter);
           ...




POO en C++: Classes Génériques           327           © 1997-2003 Fabio HERNANDEZ
Contrôle d'Avancement

   Motivation
   Déclaration d'une classe générique
   Utilisation
   Implémentation des fonctions membres
   Considérations particulières
   Fonctions génériques
   Contraintes
   Coût vs. Bénéfice
   Résumé




POO en C++: Classes Génériques        328        © 1997-2003 Fabio HERNANDEZ
Implémentation

   Spécificités syntaxiques liées à la "généricité"
   Exemple
           template<class Item>
           Item List<Item>::first() const
           {
              assert(length_ > 0);
              return data_[0];
           }

           template<class Item>
           inline
           bool List<Item>::isEmpty() const
           {
              return (length_ == 0) ? true : false;
           }

POO en C++: Classes Génériques        329         © 1997-2003 Fabio HERNANDEZ
Implémentation (suite)

   L'implémentation des fonctions membres doit être contenue
   (directe ou indirectement) lorsque l'on inclut le fichier de
   l'interface
   Fichier List.h
           #if !defined(LIST_H_INCLUDED)
           #define LIST_H_INCLUDED

           template <class Item>
           class List {
           public:
              ...
           private:
              ...
           };


POO en C++: Classes Génériques            330         © 1997-2003 Fabio HERNANDEZ
Implémentation (suite)
   Fichier List.h (suite)
           template<class Item>
           Item List<Item>::first() const
           {
              ...
           }

           template<class Item>
           inline
           bool List<Item>::isEmpty() const
           {
              ...
           }

           ...

           #endif // LIST_H_INCLUDED



POO en C++: Classes Génériques             331        © 1997-2003 Fabio HERNANDEZ
Paramètres des Classes Génériques

   Spécification de plusieurs paramètres
           template <class T1, class T2, class T3>
           class ComplicatedClass {
              public:
              ...
              private:
              ...
           };
   Création d'un objet de cette classe
           ComplicatedClass<float, int, Point> complicatedObject;




POO en C++: Classes Génériques   332             © 1997-2003 Fabio HERNANDEZ
Paramètres des Classes Génériques (suite)

   Les paramètres peuvent aussi être des expressions
           template <class Type, int Size>
           class Buffer {
              ...
           };
   Utilisation
           Buffer<double,256> littleBuffer;
           Buffer<char,1024*10> bigBuffer;

           const int MaxSize = 100;
           Buffer<bool,MaxSize> answerBuffer;




POO en C++: Classes Génériques   333            © 1997-2003 Fabio HERNANDEZ
Contrôle d'Avancement

   Motivation
   Déclaration d'une classe générique
   Utilisation
   Implémentation des fonctions membres
   Considérations particulières
   Fonctions génériques
   Contraintes
   Coût vs. Bénéfice
   Résumé




POO en C++: Classes Génériques        334        © 1997-2003 Fabio HERNANDEZ
Considérations Particulières

   Cette implémentation fonctionne-t-elle aussi bien pour les
   objets complexes que pour les objets des types primitifs?

           template <class Item>
           bool List<Item>::append(Item anItem)
           {
              if (length_ == capacity_)
                 resize();
              data_[length_] = anItem;
              ++length_;
              return true;
           }



POO en C++: Classes Génériques     335            © 1997-2003 Fabio HERNANDEZ
Considérations Particulières (suite)

   Nous devrions plutôt la modifier comme

           template <class Item>
           bool List<Item>::append(const Item& anItem)
           {
              if (length_ == capacity_)
                 resize();
              data_[length_] = anItem;
              ++length_;
              return true;
           }
   De façon similaire pour les autres fonctions membres


POO en C++: Classes Génériques   336             © 1997-2003 Fabio HERNANDEZ
Contrôle d'Avancement

   Motivation
   Déclaration d'une classe générique
   Utilisation
   Implémentation des fonctions membres
   Considérations particulières
   Fonctions génériques
   Contraintes
   Coût vs. Bénéfice
   Résumé




POO en C++: Classes Génériques        337        © 1997-2003 Fabio HERNANDEZ
Fonctions Génériques

   Syntaxe similaire à celle des classes

           template <class Type>
           Type min(Type a, Type b)
           {
              return (a < b) ? a : b;
           }

           template <class Item>
           ostream& operator<<(ostream& stream,
                               const List<Item>& aList)
           {
              ...
              return stream;
           }

POO en C++: Classes Génériques           338            © 1997-2003 Fabio HERNANDEZ
Contrôle d'Avancement

   Motivation
   Déclaration d'une classe générique
   Utilisation
   Implémentation des fonctions membres
   Considérations particulières
   Fonctions génériques
   Contraintes
   Coût vs. Bénéfice
   Résumé




POO en C++: Classes Génériques        339        © 1997-2003 Fabio HERNANDEZ
Contraintes

   L'implémentation des fonctions membres d'une classe
   générique impose des contraintes sur les classes utilisées
   comme paramètre du template
   Exemple
         la fonction membre
              int List<Item>::position(const Item& anItem) const
         suppose que la classe Item fournit l'opérateur d'égalité
         la fonction membre
              int List<Item>::append(const Item& anItem)
         suppose que la classe Item fournit l'opérateur d'affectation
   L'instance ne pourra pas être créée si ces suppositions ne sont
   pas satisfaites au moment de la compilation

POO en C++: Classes Génériques       340             © 1997-2003 Fabio HERNANDEZ
Contrôle d'Avancement

   Motivation
   Déclaration d'une classe générique
   Utilisation
   Implémentation des fonctions membres
   Considérations particulières
   Fonctions génériques
   Contraintes
   Coût vs. Bénéfice
   Résumé




POO en C++: Classes Génériques        341        © 1997-2003 Fabio HERNANDEZ
Coût vs. Bénéfice

   Avantages
         mécanisme très puissant
   Inconvénients
         syntaxe dissuasive
         pas encore (bien) supporté par quelques compilateurs
         temps de compilation/édition de liens augmenté
         taille de l'exécutable augmentée




POO en C++: Classes Génériques          342                © 1997-2003 Fabio HERNANDEZ
Résumé

   Les classes génériques servent pour décrire des conteneurs
   indépendamment du type des objets contenus
   Le client de la classe générique doit fournir les types
   nécessaires pour la création de l’instance de la classe générique
   L'implémentation des classes génériques suppose une attention
   particulière puisque le type de chaque paramètre n'est pas
   connu à priori
   Bien que normalisé, ce mécanisme n'est pas encore supporté par
   tous les compilateurs




POO en C++: Classes Génériques     343           © 1997-2003 Fabio HERNANDEZ

Contenu connexe

Tendances

Tendances (20)

Partie 13: Héritage Multiple — Programmation orientée objet en C++
Partie 13: Héritage Multiple — Programmation orientée objet en C++Partie 13: Héritage Multiple — Programmation orientée objet en C++
Partie 13: Héritage Multiple — Programmation orientée objet en C++
 
Partie 9: Fonctions Membres — Programmation orientée objet en C++
Partie 9: Fonctions Membres — Programmation orientée objet en C++Partie 9: Fonctions Membres — Programmation orientée objet en C++
Partie 9: Fonctions Membres — Programmation orientée objet en C++
 
Partie 7: Evolution du Modèle Objet — Programmation orientée objet en C++
Partie 7: Evolution du Modèle Objet — Programmation orientée objet en C++Partie 7: Evolution du Modèle Objet — Programmation orientée objet en C++
Partie 7: Evolution du Modèle Objet — Programmation orientée objet en C++
 
Partie 3: Contrôle d'Exécution — Programmation orientée objet en C++
Partie 3: Contrôle d'Exécution — Programmation orientée objet en C++Partie 3: Contrôle d'Exécution — Programmation orientée objet en C++
Partie 3: Contrôle d'Exécution — Programmation orientée objet en C++
 
Chap2fonctionscpp
Chap2fonctionscppChap2fonctionscpp
Chap2fonctionscpp
 
Chapitre2fonctionscppv2019
Chapitre2fonctionscppv2019Chapitre2fonctionscppv2019
Chapitre2fonctionscppv2019
 
Chapitre4: Pointeurs et références
Chapitre4: Pointeurs et références Chapitre4: Pointeurs et références
Chapitre4: Pointeurs et références
 
Chap1: Cours en C++
Chap1: Cours en C++Chap1: Cours en C++
Chap1: Cours en C++
 
Chapitre6: Surcharge des opérateurs
Chapitre6:  Surcharge des opérateursChapitre6:  Surcharge des opérateurs
Chapitre6: Surcharge des opérateurs
 
Chapitre1: Langage Python
Chapitre1: Langage PythonChapitre1: Langage Python
Chapitre1: Langage Python
 
Développer en natif avec C++11
Développer en natif avec C++11Développer en natif avec C++11
Développer en natif avec C++11
 
C++11 en 12 exemples simples
C++11 en 12 exemples simplesC++11 en 12 exemples simples
C++11 en 12 exemples simples
 
Chap 6 : classes et interfaces
Chap 6 : classes et interfacesChap 6 : classes et interfaces
Chap 6 : classes et interfaces
 
Chapitre5: Classes et objets
Chapitre5: Classes et objetsChapitre5: Classes et objets
Chapitre5: Classes et objets
 
Polymorphisme
PolymorphismePolymorphisme
Polymorphisme
 
Les nouveautés de C++11 : Ecrire du C++ Moderne
Les nouveautés de C++11 : Ecrire du C++ ModerneLes nouveautés de C++11 : Ecrire du C++ Moderne
Les nouveautés de C++11 : Ecrire du C++ Moderne
 
Chapitre 11: Expression Lambda et Référence de méthode en Java
Chapitre 11: Expression Lambda et Référence de méthode en JavaChapitre 11: Expression Lambda et Référence de méthode en Java
Chapitre 11: Expression Lambda et Référence de méthode en Java
 
Polymorphisme, interface et classe abstraite
Polymorphisme, interface et classe abstraitePolymorphisme, interface et classe abstraite
Polymorphisme, interface et classe abstraite
 
Ch04
Ch04Ch04
Ch04
 
Langage C
Langage CLangage C
Langage C
 

Similaire à Partie 10: Classes Génériques — Programmation orientée objet en C++

Interface collectionsinter
Interface collectionsinterInterface collectionsinter
Interface collectionsinter
RYMAA
 
Découvrez C# 4.0 et les améliorations apportées à la BCL
Découvrez C# 4.0 et les améliorations apportées à la BCLDécouvrez C# 4.0 et les améliorations apportées à la BCL
Découvrez C# 4.0 et les améliorations apportées à la BCL
DotNetHub
 
CPP PTT DE CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
CPP PTT DE CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCPP PTT DE CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
CPP PTT DE CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
SiratiSoufiane
 

Similaire à Partie 10: Classes Génériques — Programmation orientée objet en C++ (20)

POO-chapitre2.pptx
POO-chapitre2.pptxPOO-chapitre2.pptx
POO-chapitre2.pptx
 
POO-chapitre6.pptx
POO-chapitre6.pptxPOO-chapitre6.pptx
POO-chapitre6.pptx
 
FormationPython2019.pptx
FormationPython2019.pptxFormationPython2019.pptx
FormationPython2019.pptx
 
Python.pptx
Python.pptxPython.pptx
Python.pptx
 
Interface collectionsinter
Interface collectionsinterInterface collectionsinter
Interface collectionsinter
 
Boosted Java to Native Interface (JNI)
Boosted Java to Native Interface (JNI)Boosted Java to Native Interface (JNI)
Boosted Java to Native Interface (JNI)
 
Ch02
Ch02Ch02
Ch02
 
POO-chapitre3.pptx
POO-chapitre3.pptxPOO-chapitre3.pptx
POO-chapitre3.pptx
 
Découvrez C# 4.0 et les améliorations apportées à la BCL
Découvrez C# 4.0 et les améliorations apportées à la BCLDécouvrez C# 4.0 et les améliorations apportées à la BCL
Découvrez C# 4.0 et les améliorations apportées à la BCL
 
cours1.ppt
cours1.pptcours1.ppt
cours1.ppt
 
cours1.ppt
cours1.pptcours1.ppt
cours1.ppt
 
cours2.ppt
cours2.pptcours2.ppt
cours2.ppt
 
Theme 7
Theme 7Theme 7
Theme 7
 
C++ 11/14
C++ 11/14C++ 11/14
C++ 11/14
 
Part1
Part1Part1
Part1
 
02 Spécificité du C++ COURS SYS SYSSSSSS
02 Spécificité du C++  COURS SYS SYSSSSSS02 Spécificité du C++  COURS SYS SYSSSSSS
02 Spécificité du C++ COURS SYS SYSSSSSS
 
Cours C Avancé chapitre 2 et chapitre.pdf
Cours C Avancé  chapitre 2 et chapitre.pdfCours C Avancé  chapitre 2 et chapitre.pdf
Cours C Avancé chapitre 2 et chapitre.pdf
 
Introduction à Python
Introduction à PythonIntroduction à Python
Introduction à Python
 
CPP PTT DE CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
CPP PTT DE CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCPP PTT DE CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
CPP PTT DE CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
 
IMPLEMENTATION EN PYTHON DES CONVENTIONS ALGORITHMIQUES (2022-2023)
IMPLEMENTATION EN PYTHON DES CONVENTIONS ALGORITHMIQUES  (2022-2023)IMPLEMENTATION EN PYTHON DES CONVENTIONS ALGORITHMIQUES  (2022-2023)
IMPLEMENTATION EN PYTHON DES CONVENTIONS ALGORITHMIQUES (2022-2023)
 

Partie 10: Classes Génériques — Programmation orientée objet en C++

  • 1. Programmation Orientée Objet en C++ 10ème Partie: Classes Génériques Fabio Hernandez Fabio.Hernandez@in2p3.fr
  • 2. Vue d'Ensemble Notions de base Types, variables, opérateurs Contrôle d'exécution Fonctions Mémoire dynamique Qualité du logiciel Evolution du modèle objet Objets et classes Fonctions membres Classes génériques Héritage Polymorphisme Héritage multiple Entrée/sortie POO en C++: Classes Génériques 314 © 1997-2003 Fabio HERNANDEZ
  • 3. Table des Matières Motivation Déclaration d'une classe générique Utilisation Implémentation des fonctions membres Considérations particulières Fonctions génériques Contraintes Coût vs. Bénéfice Résumé POO en C++: Classes Génériques 315 © 1997-2003 Fabio HERNANDEZ
  • 4. Motivation Nous avons étudié les facilités offertes par C++ pour créer des classes permettant de définir des conteneurs d'objets d'un même type Un conteneur est un objet qui agit sur une collection de zéro ou plusieurs objets d'une classe particulière Les classes List et Queue et les tableaux sont des exemples des classes conteneurs Le type des objets contenus dans un objet de la classe List ou de la classe Queue est float Les services de ces classes (append, prepend, insert, remove,...) ne dépendent pas du type des objets qu'elles contiennent POO en C++: Classes Génériques 316 © 1997-2003 Fabio HERNANDEZ
  • 5. Motivation (suite) Supposons que nous voulons créer une List d'objets de type char Une possible solution consiste à dupliquer le code déjà écrit pour la classe List en faisant les modifications pour que les objets contenus soient de type char et pas float il faudrait aussi renommer les classes (FloatList, CharList,...) cette solution pose des problèmes pour la maintenance du code Une autre possible solution est d'utiliser les facilités de définition de macros du pré-processeur pour générer le code nécessaire sur demande du programmeur problèmes de maintenance particulièrement inélégant POO en C++: Classes Génériques 317 © 1997-2003 Fabio HERNANDEZ
  • 6. Motivation (suite) C++ fournit un mécanisme permettant de définir des classes (et des fonctions) génériques (paramétrables) L'idée est d'écrire des "moules" permettant de construire d'autres classes particulièrement utile pour les conteneurs le paramètre de la classe correspond au type des objets contenus En C++ cette facilité est connue sous le nom de template Nous allons étudier à nouveau la classe List et la modifier de façon à ce qu'elle devienne générique POO en C++: Classes Génériques 318 © 1997-2003 Fabio HERNANDEZ
  • 7. Contrôle d'Avancement Motivation Déclaration d'une classe générique Utilisation Implémentation des fonctions membres Considérations particulières Fonctions génériques Contraintes Coût vs. Bénéfice Résumé POO en C++: Classes Génériques 319 © 1997-2003 Fabio HERNANDEZ
  • 8. Déclaration #if !defined(LIST_H_INCLUDED) #define LIST_H_INCLUDED Item est le template <class Item> paramètre de class List { la classe List public: // Constructors/Destructor List(); List(int initialCapacity); List(const List& aList); ~List(); // Modifiers bool append(Item anItem); bool prepend(Item anItem); bool insert(Item anItem, int position); bool remove(Item anItem); POO en C++: Classes Génériques 320 © 1997-2003 Fabio HERNANDEZ
  • 9. Déclaration (suite) bool removeAll(Item anItem); bool replace(int position, Item anItem); bool replaceAll(Item item1, Item item2); void clear(); // Selectors int length() const; int occurrences(Item anItem) const; int position(Item anItem) const; Item itemAt(int position) const; Item first() const; Item last() const; bool isEqual(const List& aList) const; bool isEmpty() const; POO en C++: Classes Génériques 321 © 1997-2003 Fabio HERNANDEZ
  • 10. Déclaration (suite) private: // Data members Item* data_; int capacity_; int length_; // Help functions void resize(); }; #endif // LIST_H_INCLUDED POO en C++: Classes Génériques 322 © 1997-2003 Fabio HERNANDEZ
  • 11. Contrôle d'Avancement Motivation Déclaration d'une classe générique Utilisation Implémentation des fonctions membres Considérations particulières Fonctions génériques Contraintes Coût vs. Bénéfice Résumé POO en C++: Classes Génériques 323 © 1997-2003 Fabio HERNANDEZ
  • 12. Utilisation Pour utiliser (créer une instance d') une classe générique il faut fournir les paramètres nécessaires Fichier main.cpp #include "List.h" void main() { Création d’une List<char> alphabet; instance de la classe alphabet.append('z'); générique avec le type alphabet.prepend('a'); primitif char comme paramètre if (alphabet.isEmpty()) ... cout << "Length = " << alphabet.length() << endl; ... } POO en C++: Classes Génériques 324 © 1997-2003 Fabio HERNANDEZ
  • 13. Utilisation (suite) De façon similaire pour les listes des autres types primitifs List<float> hitList; List<int> counterList; ... On peut aussi créer des instances des classes génériques avec comme paramètre d'autres classes #include "Point.h" #include "List.h" List<Point> vertexList; // A List of Point objects POO en C++: Classes Génériques 325 © 1997-2003 Fabio HERNANDEZ
  • 14. Utilisation (suite) Notez que les instances des classes génériques sont complètement identifiées par le nom de la classe et ses paramètres List<int> counterList; List<char> alphabet; ... // COMPILATION ERROR: 'counterList' and // 'alphabet' are two objets of a different class if (counterList.isEqual(alphabet)) cout << "They are equal" << endl; POO en C++: Classes Génériques 326 © 1997-2003 Fabio HERNANDEZ
  • 15. Utilisation (suite) Afin de faciliter l'écriture, on peut définir des synonymes #include "List.h" Définition d'un typedef List<char> CharList; synonyme d'une ... classe générique CharList alphabet; alphabet.clear(); for(char letter='a'; letter <= 'z'; ++letter) alphabet.append(letter); ... POO en C++: Classes Génériques 327 © 1997-2003 Fabio HERNANDEZ
  • 16. Contrôle d'Avancement Motivation Déclaration d'une classe générique Utilisation Implémentation des fonctions membres Considérations particulières Fonctions génériques Contraintes Coût vs. Bénéfice Résumé POO en C++: Classes Génériques 328 © 1997-2003 Fabio HERNANDEZ
  • 17. Implémentation Spécificités syntaxiques liées à la "généricité" Exemple template<class Item> Item List<Item>::first() const { assert(length_ > 0); return data_[0]; } template<class Item> inline bool List<Item>::isEmpty() const { return (length_ == 0) ? true : false; } POO en C++: Classes Génériques 329 © 1997-2003 Fabio HERNANDEZ
  • 18. Implémentation (suite) L'implémentation des fonctions membres doit être contenue (directe ou indirectement) lorsque l'on inclut le fichier de l'interface Fichier List.h #if !defined(LIST_H_INCLUDED) #define LIST_H_INCLUDED template <class Item> class List { public: ... private: ... }; POO en C++: Classes Génériques 330 © 1997-2003 Fabio HERNANDEZ
  • 19. Implémentation (suite) Fichier List.h (suite) template<class Item> Item List<Item>::first() const { ... } template<class Item> inline bool List<Item>::isEmpty() const { ... } ... #endif // LIST_H_INCLUDED POO en C++: Classes Génériques 331 © 1997-2003 Fabio HERNANDEZ
  • 20. Paramètres des Classes Génériques Spécification de plusieurs paramètres template <class T1, class T2, class T3> class ComplicatedClass { public: ... private: ... }; Création d'un objet de cette classe ComplicatedClass<float, int, Point> complicatedObject; POO en C++: Classes Génériques 332 © 1997-2003 Fabio HERNANDEZ
  • 21. Paramètres des Classes Génériques (suite) Les paramètres peuvent aussi être des expressions template <class Type, int Size> class Buffer { ... }; Utilisation Buffer<double,256> littleBuffer; Buffer<char,1024*10> bigBuffer; const int MaxSize = 100; Buffer<bool,MaxSize> answerBuffer; POO en C++: Classes Génériques 333 © 1997-2003 Fabio HERNANDEZ
  • 22. Contrôle d'Avancement Motivation Déclaration d'une classe générique Utilisation Implémentation des fonctions membres Considérations particulières Fonctions génériques Contraintes Coût vs. Bénéfice Résumé POO en C++: Classes Génériques 334 © 1997-2003 Fabio HERNANDEZ
  • 23. Considérations Particulières Cette implémentation fonctionne-t-elle aussi bien pour les objets complexes que pour les objets des types primitifs? template <class Item> bool List<Item>::append(Item anItem) { if (length_ == capacity_) resize(); data_[length_] = anItem; ++length_; return true; } POO en C++: Classes Génériques 335 © 1997-2003 Fabio HERNANDEZ
  • 24. Considérations Particulières (suite) Nous devrions plutôt la modifier comme template <class Item> bool List<Item>::append(const Item& anItem) { if (length_ == capacity_) resize(); data_[length_] = anItem; ++length_; return true; } De façon similaire pour les autres fonctions membres POO en C++: Classes Génériques 336 © 1997-2003 Fabio HERNANDEZ
  • 25. Contrôle d'Avancement Motivation Déclaration d'une classe générique Utilisation Implémentation des fonctions membres Considérations particulières Fonctions génériques Contraintes Coût vs. Bénéfice Résumé POO en C++: Classes Génériques 337 © 1997-2003 Fabio HERNANDEZ
  • 26. Fonctions Génériques Syntaxe similaire à celle des classes template <class Type> Type min(Type a, Type b) { return (a < b) ? a : b; } template <class Item> ostream& operator<<(ostream& stream, const List<Item>& aList) { ... return stream; } POO en C++: Classes Génériques 338 © 1997-2003 Fabio HERNANDEZ
  • 27. Contrôle d'Avancement Motivation Déclaration d'une classe générique Utilisation Implémentation des fonctions membres Considérations particulières Fonctions génériques Contraintes Coût vs. Bénéfice Résumé POO en C++: Classes Génériques 339 © 1997-2003 Fabio HERNANDEZ
  • 28. Contraintes L'implémentation des fonctions membres d'une classe générique impose des contraintes sur les classes utilisées comme paramètre du template Exemple la fonction membre int List<Item>::position(const Item& anItem) const suppose que la classe Item fournit l'opérateur d'égalité la fonction membre int List<Item>::append(const Item& anItem) suppose que la classe Item fournit l'opérateur d'affectation L'instance ne pourra pas être créée si ces suppositions ne sont pas satisfaites au moment de la compilation POO en C++: Classes Génériques 340 © 1997-2003 Fabio HERNANDEZ
  • 29. Contrôle d'Avancement Motivation Déclaration d'une classe générique Utilisation Implémentation des fonctions membres Considérations particulières Fonctions génériques Contraintes Coût vs. Bénéfice Résumé POO en C++: Classes Génériques 341 © 1997-2003 Fabio HERNANDEZ
  • 30. Coût vs. Bénéfice Avantages mécanisme très puissant Inconvénients syntaxe dissuasive pas encore (bien) supporté par quelques compilateurs temps de compilation/édition de liens augmenté taille de l'exécutable augmentée POO en C++: Classes Génériques 342 © 1997-2003 Fabio HERNANDEZ
  • 31. Résumé Les classes génériques servent pour décrire des conteneurs indépendamment du type des objets contenus Le client de la classe générique doit fournir les types nécessaires pour la création de l’instance de la classe générique L'implémentation des classes génériques suppose une attention particulière puisque le type de chaque paramètre n'est pas connu à priori Bien que normalisé, ce mécanisme n'est pas encore supporté par tous les compilateurs POO en C++: Classes Génériques 343 © 1997-2003 Fabio HERNANDEZ