Dans la conclusion du cours, nous affirmons qu’un intérêt du polymorphisme, c’est de pouvoir écrire un algorithme « générique », c’est à dire un algorithme qui pourra fonctionner pour des objets représentant des données de plusieurs types.
Nous considérons un algorithme de tri très simple qui fonctionne sur des entiers :
void insertion_sort(std::vector<int>& anArray) { for (int i = 0; i < anArray.size(); i++) { for (int j = i + 1; j < anArray.size(); j++) { if (anArray[i] > anArray[j]) std::swap(anArray[i], anArray[j]); } } }
Cet algorithme fonctionne uniquement pour des entiers. Nous nous proposons de transformer cette fonction afin qu’elle puisse aussi bien trier des entiers mais aussi des réels ou des complexes.
Pour ce faire, nous concevons une classe « abstraite » ayant comme nom « Base » qui expose les fonctions nécessaires à l’écriture de l’algorithme de tri.
Nous souhaitons utiliser l’algorithme avec la signature suivante :
void insertion_sort(std::vector<Base*>& anArray)
Quelles sont les méthodes virtuelles que la classe abstraite doit exposer ?
Ajouter à la classe de base Base
une méthode purement virtuelle print()
qui affiche le contenu de la classe sur la console.
Créer une fonction print(std::vector<Base*> anArray)
qui prend un tableau en paramètre et affiche l’ensemble des éléments contenus dans le tableau sur la console.
Créer une classe Entier qui dérive de la classe « abstraite » Base
et qui contient un champ m_value
ayant comme type le type int
.
Créer une fonction qui crée un tableau de theNumberOfValues
entiers de type Entier
std::vector<Base*> create_integer_array( size_t theNumberOfValues)
qui crée un tableau de theNumberOfValues
valeurs commençant par la valeur 0
et se terminant à la valeur theNumberOfValues-1
.
Créer une fonction qui crée un tableau de theNumberOfValues
entiers de type Entier
dont les éléments sont des nombres aléatoires compris entre theMinValue
et theMaxValue
.
Cette fonction peut s’implanter comme suit.
std::vector<Base*> create_random_integer_array( size_t theNumberOfValues, int theMinValue, int theMaxValue) { std::random_device rd; std::mt19937 gen(rd()); std::uniform_int_distribution<> distr(theMinValue, theMaxValue); std::vector<Base*> array(theNumberOfValues); for (size_t i = 0; i < theNumberOfValues; i++) array[i] = new Entier(distr(gen)); return array; }
Modifier la fonction de tri insertion_sort(std::vector<int>& anArray)
afin de ne plus travailler sur des entiers mais sur des objets dérivant de la classe « abstraite » Base
:
void insertion_sort(std::vector<Base*>& anArray)
Tester la fonction avec le tableau d’entiers que vous avez créé à la question n°3.3.
Nous souhaitons étendre le code à une classe de réel.
Ecrire une nouvelles classe Reel
qui dérive de Base
et qui contient un champ m_value
de type double
.
Créer une fonction qui crée un tableau de theNumberOfValues
objets de type Reel
dont les éléments sont des nombres aléatoires compris entre theMinValue
et theMaxValue
.
Cette fonction peut s’implanter comme suit.
std::vector<Base*> create_random_double_array( size_t theNumberOfValues, double theMinValue, double theMaxValue) { std::random_device rd; std::mt19937 gen(rd()); std::uniform_real_distribution<> distr(theMinValue, theMaxValue); std::vector<Base*> array(theNumberOfValues); for (size_t i = 0; i < theNumberOfValues; i++) array[i] = new Reel(distr(gen)); return array; }
Vérifier que l’algorithme de tri fonctionne aussi pour cette nouvelle nouvelle classe.