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 :
- des fonctions génériques
- ou des classes génériques
On utilise le mot clé template pour déclarer une fonction ou une classe générique.
Fonction générique
#include <iostream>
#include <cstdlib>
using namespace std;
/**
* function that computes minimum of two values
*/
template<class T>
T minimum(T a, T b) {
return (a < b) ? a : b;
}
/**
* function that computes minimum of two values
* using a Predicate, here a function of the form
* bool Predicate(T a, T b)
* or
* bool Predicate(T& a, T& b)
*/
template<class T, class Predicate>
T minimum(T a, T b, Predicate p) {
return p(a, b) ? a : b;
}
/**
* class Person with name and age
*/
class Person {
protected:
string name;
int age;
public:
Person(string n, int a) : name(n), age(a) {
}
string get_name() {
return name;
}
int get_age() {
return age;
}
/**
* redefinition of <<
*/
friend ostream& operator<<(ostream& out, const Person& p) {
out << p.name << ", " << p.age;
return out;
}
/**
* definition of less than operator two compare two person's age
*
*/
friend bool operator<(const Person& lhs, const Person& rhs) {
return lhs.age < rhs.age;
}
};
/**
* main function
*/
int main() {
// integer
int min_i = minimum(2, 1);
cout << "min int = " << min_i << endl;
// float
float min_f = minimum(3.0, 2.0);
cout << "min float = " << min_f << endl;
// Person
// will only work if the operator < has been defined
// for the class Person
Person riri("riri", 10);
Person fifi("fifi", 11);
Person p_min_age = minimum(riri, fifi);
cout << "min age = " << p_min_age << endl;
Person p_min_name = minimum(riri, fifi, [](Person& lhs, Person& rhs) {
return lhs.get_name() < rhs.get_name();
});
cout << "min name = " << p_min_name << endl;
return EXIT_SUCCESS;
}
Classe générique
Il est préférable de déclarer l'ensemble des méthodes inline dans un fichier header .h :
#ifndef VECTOR_H
#define VECTOR_H
/**
***********************************************
* Vector of elements
***********************************************
*/
template<class T>
class Vector {
// =============================================
// data members
// =============================================
protected:
// maximum number of elements
int max_size;
// dynamic array of elements
T *elements;
// =============================================
// methods
// =============================================
public:
// -----------------------------------------
// default constructor with 10 elements
// -----------------------------------------
Vector(int sz = 10) {
max_size = sz;
elements = new T [ max_size ];
}
// -----------------------------------------
// copy constructor
// -----------------------------------------
Vector(Vector& v) {
max_size = v.max_size;
elements = new T [ max_size ];
for (int i=0; i<max_size; ++i) {
elements[i] = v.elements[i];
}
}
// -----------------------------------------
// assignment operator
// -----------------------------------------
Vector& operator=(Vector& v) {
if (&v != this) {
delete [] elements;
max_size = v.max_size;
elements = new T [ max_size ];
for (int i=0; i<max_size; ++i) {
elements[i] = v.elements[i];
}
}
return *this;
}
// -----------------------------------------
// destructor
// -----------------------------------------
~Vector() {
delete [] elements;
}
// -----------------------------------------
// accessor
// -----------------------------------------
T& operator[](int n) {
return elements[n];
}
// -----------------------------------------
// getter
// -----------------------------------------
int get_size() {
return max_size;
}
};
#endif