2. C++ Avancé




La Généricité

La Généricité est un concept des langages de haut niveau qui consiste à définir des algorithmes identiques opérant sur des données de types différents.

Il est possible de créer :

On utilise le mot clé template pour déclarer une fonction ou une classe générique.

Fonction générique

  1. #include <iostream>
  2. #include <cstdlib>
  3. using namespace std;
  4.  
  5. /**
  6.  * function that computes minimum of two values
  7.  */
  8. template<class T>
  9. T minimum(T a, T b) {
  10.     return (a < b) ? a : b;
  11. }
  12.  
  13. /**
  14.  * function that computes minimum of two values
  15.  * using a Predicate, here a function of the form
  16.  * bool Predicate(T a, T b)
  17.  * or
  18.  * bool Predicate(T& a, T& b)
  19.  */
  20. template<class T, class Predicate>
  21. T minimum(T a, T b, Predicate p) {
  22.     return p(a, b) ? a : b;
  23. }
  24.  
  25. /**
  26.  * class Person with name and age
  27.  */
  28. class Person {
  29. protected:
  30.     string name;
  31.     int age;
  32.    
  33. public:
  34.     Person(string n, int a) : name(n), age(a) {
  35.     }
  36.    
  37.     string get_name() {
  38.         return name;
  39.     }
  40.    
  41.     int get_age() {
  42.         return age;
  43.     }
  44.    
  45.     /**
  46.      * redefinition of <<
  47.      */
  48.     friend ostream& operator<<(ostream& out, const Person& p) {
  49.         out << p.name << ", " << p.age;
  50.         return out;
  51.     }
  52.    
  53.     /**
  54.      * definition of less than operator two compare two person's age
  55.      *
  56.      */
  57.     friend bool operator<(const Person& lhs, const Person& rhs) {
  58.         return lhs.age < rhs.age;
  59.     }
  60. };
  61.  
  62. /**
  63.  * main function
  64.  */
  65. int main() {
  66.     // integer
  67.     int min_i = minimum(2, 1);
  68.     cout << "min int = " << min_i << endl;
  69.     // float
  70.     float min_f = minimum(3.0, 2.0);
  71.     cout << "min float = " << min_f << endl;
  72.  
  73.     // Person
  74.     // will only work if the operator < has been defined
  75.     // for the class Person
  76.     Person riri("riri", 10);
  77.     Person fifi("fifi", 11);
  78.  
  79.     Person p_min_age = minimum(riri, fifi);
  80.  
  81.     cout << "min age = " << p_min_age << endl;
  82.    
  83.     Person p_min_name = minimum(riri, fifi, [](Person& lhs, Person& rhs) {
  84.         return lhs.get_name() < rhs.get_name();
  85.     });
  86.    
  87.     cout << "min name = " << p_min_name << endl;
  88.  
  89.     return EXIT_SUCCESS;
  90. }
  91.  

Classe générique

Il est préférable de déclarer l'ensemble des méthodes inline dans un fichier header .h :

  1. #ifndef VECTOR_H
  2. #define VECTOR_H
  3.  
  4. /**
  5.  ***********************************************
  6.  * Vector of elements
  7.  ***********************************************
  8.  */
  9. template<class T>
  10. class Vector {
  11. // =============================================
  12. // data members
  13. // =============================================
  14. protected:
  15.     // maximum number of elements
  16.     int max_size;
  17.     // dynamic array of elements
  18.     T *elements;
  19.    
  20. // =============================================
  21. // methods
  22. // =============================================   
  23. public:
  24.     // -----------------------------------------
  25.     // default constructor with 10 elements
  26.     // -----------------------------------------
  27.     Vector(int sz = 10) {
  28.         max_size = sz;
  29.         elements = new T [ max_size ];
  30.     }
  31.    
  32.     // -----------------------------------------
  33.     // copy constructor
  34.     // -----------------------------------------
  35.     Vector(Vector& v) {
  36.         max_size = v.max_size;
  37.         elements = new T [ max_size ];
  38.         for (int i=0; i<max_size; ++i) {
  39.             elements[i] = v.elements[i];
  40.         }
  41.     }
  42.    
  43.     // -----------------------------------------
  44.     // assignment operator
  45.     // -----------------------------------------
  46.     Vector& operator=(Vector& v) {
  47.         if (&v != this) {
  48.             delete [] elements;
  49.             max_size = v.max_size;
  50.             elements = new T [ max_size ];
  51.             for (int i=0; i<max_size; ++i) {
  52.                 elements[i] = v.elements[i];
  53.             }
  54.         }
  55.         return *this;
  56.     }
  57.    
  58.     // -----------------------------------------
  59.     // destructor
  60.     // -----------------------------------------
  61.     ~Vector() {
  62.         delete [] elements;
  63.     }
  64.    
  65.     // -----------------------------------------
  66.     // accessor
  67.     // -----------------------------------------
  68.     T& operator[](int n) {
  69.         return elements[n];
  70.     }
  71.    
  72.     // -----------------------------------------
  73.     // getter
  74.     // -----------------------------------------
  75.     int get_size() {
  76.         return max_size;
  77.     }
  78. };
  79. #endif
  80.