Cet exercice correspond à l'exercice «pas à pas» page 145 de l'ouvrage C++ par la pratique (3e édition, PPUR).

Introduction

Le but de cet exercice est d'illustrer la notion de polymorphisme en utilisant une collection hétérogène de véhicules.

Dans le fichier aeroport.cc, commencez par définir des classes Vehicule, Avion et Voiture. Les avions et les voitures sont des véhicules. Dotez chacune de ces classes d'une méthode permettant de les afficher (message quelconque au choix).

On souhaite ensuite créer une classe Aeroport ayant à gérer un ensemble de véhicules constitué à la fois de voitures et d'avions.

Sans polymorphisme, du fait que l'on manipule deux types d'objets différents, on est obligé de créer deux tableau différents ; ceci est parfaitement valable en soit, mais pour les besoins de l'exercices supposons ici que l'on souhaiterait plutôt les gérer ensembles comme une collection de véhicules, sans distinction à ce stade (collection).

Définissez la classe Aeroport dans cet esprit. Dotez-la de trois méthodes :

  • affiche_vehicules(ostream&) permettant d'afficher tous les véhicules de l'aéroport ;
  • ajouter_vehicules(...) permettant d'ajouter un véhicule à l'aéroport ;
  • vider_vehicules() supprimant tous les véhicules de l'aéroport

[Essayez de le faire par vous même avant de regarder la solution qui suit]

Cliquez ici pour voir/cacher le code.



Pour que la résolution dynamique des liens puisse être mise en œuvre, il faut aussi que les méthodes que l'on invoque sur les objets de type Vehicule soient virtuelles.

De cette façon, si vehicules[i] est un (pointeur sur un) avion vehicules[i]->afficher() fera appel à la méthode d'affichage de la classe Avion et non la méthode de Vehicule.

Notre classe Vehicule doit donc être :

class Vehicule {
public:
  Vehicule(// par exemple...
           string marque, unsigned int date, double prix
          );
  virtual void affiche(ostream&) const;
  virtual ~Vehicule() {}

protected:
 // par exemple....
  string       marque       ;
  unsigned int date_achat   ;
  double       prix_achat   ;
  double       prix_courant ;
};

Voilà, notre classe Aeroport est maintenant utilisable.

Pour que le codage en soit complètement satisfaisant, il faudrait cependant pouvoir offrir le moyen d'éventuellement pouvoir libérer la mémoire des objets mis dans la collection (au cas où la fonction qui les a créés et ajouté à la collection souhaite les supprimer).
(En tout rigueur il faudrait aussi pouvoir en supprimer 1 élément précis et fournir une méthode de copie profonde au cas où).

Ajoutez une méthode supprimer_vehicules() qui effectue ce nettoyage mémoire.

Vous pouvez alors tester avec le main() suivant :

int main() {
   Aeroport gva;
   gva.ajouter_vehicule(new
       Voiture("Peugeot", 1998, 147325.79, 2.5, 5, 180.0, 12000));
   gva.ajouter_vehicule(new 
       Voiture("Porsche",  1985, 250000.00, 6.5, 2, 280.0, 81320));
   gva.ajouter_vehicule(new 
       Avion("Cessna",     1972, 1230673.90, HELICES,   250));
   gva.ajouter_vehicule(new 
       Avion("Nain Connu", 1992, 4321098.00, REACTION, 1300));
   gva.ajouter_vehicule(new 
       Voiture("Fiat",    2001,   7327.30, 1.6, 3,  65.0,  3000));

  gva.affiche_vehicules(cout);

  // pour être propre, le main() demande (à gva) de libérer
  // la mémoire qu'il (main) a alloué (et c'est à lui (main) de le faire
  // pas au destructeur de gva qui n'a pas alloué cette mémoire)
  gva.supprimer_vehicules();

  return 0;
}

[NOTE : Comme dans toute collection hétérogène construite par pointeurs, il faut faire attention à la gestion de la mémoire.
Nous avons volontairement écarté ici l'aspect allocation dynamique (qui n'est pas nécessaire mais souvent utile) ici, et laissez le soin à la fonction main() de s'en charger de façon simple, mais si cette allocation dynamique devait être géré au niveau de la classe Aeroport, il faudrait bien entendu le faire proprement, avec constructeur de copie, copie profonde, libération par le destructeur, surcharge de l'opérateur d'affectation (=), etc. ]

Vous pouvez trouver ici un code complet possible :

Cliquez ici pour voir/cacher le code.



Dernière mise à jour le 22 avril 2015
Last modified: Wed Apr 22, 2015