Série 22 :
Polymorphisme et collection hétérogènes
Buts
Cette série a pour but de continuer à vous faire pratiquer le polymorphismePréliminaires :
Avant de commencer les exercices décrits dans
cette série, créez le répertoire
~/Desktop/myfiles/Programmation/cpp/serie22 et travaillez dans ce
répertoire pour les exercices
ne faisant pas partie du projet.
Si vous n'avez pas le temps de faire la partie "exercices" de la série, veillez au moins à en consulter le corrigé.
Exercice 1 : encore des figures géométriques (polymorphisme, niveau 2)
Exercice n°61 (pages 151 et 338) de l'ouvrage C++ par la pratique.
Le but de cet
exercice est d'arriver à définir une collection hétérogène de figures géométriques.
Nous nous limiterons, dans un premier temps, à une solution partielle... mais instructive.
Dans le fichier figures.cc, prototypez et définissez les classes suivantes : (vous pouvez adapter ce qui avait été réalisé dans l'exercice précédent).
- La classe abstraite Figure, ne possédant aucun attribut, et trois méthodes :
-
- affiche, publique, constante, virtuelle pure, et n'admettant aucun argument.
- une méthode Figure* copie() const, également virtuelle pure, chargée de faire une copie en mémoire de l'objet et de retourner le pointeur sur cette copie
- Trois sous-classes (héritage publique) de Figure : Cercle, Carre et Triangle.
- Une classe nommée Dessin, qui modélise une collection de figures. Il s'agira d'une collection «hétérogène» d'éléments créés dynamiquement par une méthode ad-hoc définie plus bas (ajouteFigure) .
Définissez également, pour chacune de ces sous-classes, un constructeur pouvant être utilisé comme constructeur par défaut, un constructeur de copie et un destructeur.
Dans les 3 cas, affichez un message indiquant le type de l'objet et la nature du constructeur/destructeur.
Définissez la méthode de copie en utilisant le constructeur de copie.
Finalement, définissez la méthode virtuelle affiche, affichant le type de l'instance et la valeur de ses attributs.
Ajoutez un destructeur explicite pour la classe Dessin, et définissez-le de sorte qu'il détruise les figures stockées dans la collection en libérant leur espace mémoire (puisque c'est cette classe Dessin qui, dans sa méthode ajouteFigure, alloue cette mémoire).
Comme pour les autres destructeurs, affichez en début de bloc un message, afin de permettre le suivi du déroulement des opérations.
Prototypez et définissez ensuite les méthodes suivantes à la classe Dessin :
void ajouteFigure(const Figure& fig)
qui ajoute à la collection une copie de la figure donnée en paramètre en faisant appel à sa méthode copie.void affiche() const
qui affiche de tous les éléments de la collection.
int main()
{
Dessin dessin;
dessin.ajouteFigure(Triangle(3,4));
dessin.ajouteFigure(Carre(2));
dessin.ajouteFigure(Triangle(6,1));
dessin.ajouteFigure(Cercle(12));
cout << endl << "Affichage du dessin : " << endl;
dessin.affiche();
}
Si vous avez suivi les directives de l'énoncé, votre programme devrait, en dernier lieu,
indiquer que le destructeur du dessin est invoqué... mais pas les destructeurs des figures
stockées dans le dessin !
Pourquoi ?
Voyez-vous un moyen permettant de pallier à cela ?
Corrigez (en ajoutant 1 seul mot) votre programme.
Ajoutez la fonction suivante, juste avant votre main :
void unCercleDePlus(const Dessin& img)
{
Dessin tmp(img);
tmp.ajouteFigure(Cercle(1));
cout << "Affichage de 'tmp': " << endl;
tmp.affiche();
}
Si tout se passe 'normalement', le système doit interrompre prématurément votre programme, en vous adressant un message hargneux (genre «segmentation fault», ou «bus error»).
Quel est, à votre avis, le motif d'un tel comportement ?
Projet
Projet : continuationCette semaine, vous devez commencer à coder l'étape 3 de l'énoncé.