Série 20 :
Héritage
Buts
Cette série a pour but principal de vous faire faire pratiquer la notion d'héritage.Préliminaires :
Avant de commencer les exercices décrits dans cette série, créez le répertoire ~/Desktop/myfiles/Programmation/cpp/serie20 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é. Ceci vous donnera de précieuses indications pour le codage de votre projet.
Exercice 0 : reprise de l'exemple du cours (Héritage, niveau 0)
Cliquez ici si vous souhaitez faire cet exercice.
Exercice 1 : Véhicules (niveau 1)
1.1 La classe Vehicule
Dans un fichier Vehicule.cc, définissez une classe Vehicule qui a pour attributs des informations valables pour tout type de véhicule:- sa marque
- sa date d'achat
- son prix d'achat
- son prix courant
Définissez une méthode publique void affiche(ostream&) const; qui affiche l'état de l'instance, i.e. la valeur de ses attributs. , et surchargez l'operateur externe ostream& operator<<(ostream&, const Vehicule&).
1.2 La classe Voiture et la classe Avion
Définissez deux classes Voiture et Avion, héritant de la classe Vehicule et ayant les attributs supplémentaires suivants :- pour la classe Voiture :
-
- sa cylindrée
- son nombre de portes
- sa puissance
- son kilométrage
- pour la classe Avion :
-
- son type (hélices ou réaction)
- son nombre d'heures de vol
Encore des méthodes
Ajoutez une méthode void calculePrix() dans la classe Vehicule qui à ce niveau fixe le prix courant au prix d'achat moins 1% par année entre la date d'achat et la date actuelle (1 % d'amortissement).Utilisez le littéral 2022 pour l'année courante.
Redéfinissez cette méthode dans les deux sous-classes Voiture et Avion, afin de pouvoir calculer le prix courant en fonction de certains critères, et mettre à jour l'attribut correspondant au prix courant :
- Pour une voiture, le prix courant est égal au prix d'achat, moins :
-
- 2% pour chaque année depuis sa fabrication jusqu'à la date actuelle
- 5% pour chaque tranche de 10000km parcourus (on arrondit à la tranche la plus proche)
- 10% s'il s'agit d'un véhicule de marque "Renault" ou "Fiat" (ou d'autres marques de votre choix)
- et plus 20% s'il s'agit d'un véhicule de marque "Ferrari" ou "Porsche" (idem)
- Pour un avion, le prix courant est égal au prix d'achat, moins :
-
- 10 % pour chaque tranche de 1000 heures de vol s'il s'agit d'un avion à réaction
- 10 % pour chaque tranche de 100 heures de vol s'il s'agit d'un avion à hélices
Le main
Afin de tester les méthodes implémentées ci-dessus, complétez le main comme suit :int main() { vector<voiture> garage; vector<avion> hangar; garage.push_back(Voiture("Peugeot", 1998, 147325.79, 2.5, 5, 180.0, 12000)); garage.push_back(Voiture("Porsche", 1985, 250000.00, 6.5, 2, 280.0, 81320)); garage.push_back(Voiture("Fiat", 2001, 7327.30, 1.6, 3, 65.0, 3000)); hangar.push_back(Avion("Sesna", 1972, 1230673.90, HELICES, 250)); hangar.push_back(Avion("Nain Connu", 1992, 4321098.00, REACTION, 1300)); for (unsigned int i(0); i < garage.size(); i++) { garage[i].calculePrix(); garage[i].affiche(cout); } for (unsigned int i(0); i < hangar.size(); i++) { hangar[i].calculePrix(); hangar[i].affiche(cout); } return 0; }
Exemple d'exécution :
---- Voiture ---- marque : Peugeot, date d'achat : 1998, prix d'achat : 147326, prix actuel : 88395.5 2.5 litres, 5 portes, 180 CV, 12000 km. ---- Voiture ---- marque : Porsche, date d'achat : 1985, prix d'achat : 250000, prix actuel : 48350 6.5 litres, 2 portes, 280 CV, 81320 km. ---- Voiture ---- marque : Fiat, date d'achat : 2001, prix d'achat : 7327.3, prix actuel : 4433.02 1.6 litres, 3 portes, 65 CV, 3000 km. ---- Avion à hélices ---- marque : Cessna, date d'achat : 1972, prix d'achat : 1.23067e+06, prix actuel : 923005 250 heures de vol. ---- Avion à réaction ---- marque : Nain Connu, date d'achat : 1992, prix d'achat : 4.3211e+06, prix actuel : 3.75936e+06 1300 heures de vol.
Exercice 2 : Vaccins (niveau 1)
Une compagnie pharmaceutique souhaite connaître les coûts de fabrication des vaccins qu'elle produit.
Ouvrez un fichier vaccin.cc et copiez-y le code suivant (qu'il s'agira de compléter) :
#include <string> #include <vector> #include <iostream> using namespace std; // prix du conditionnement d'une unité const double COND_UNITE(0.5); // prix de base de fabrication d'une unité const double PRIX_BASE(1.5); // majoration du prix de fabrication pour vaccin "high tech" const double MAJORATION_HIGHTECH(0.5); // reduction du cout du à la delocalisation const double REDUCTION_DELOC(0.2); enum Fabrication {Standard, HighTech}; // CLASSES A COMPLETER ICI // ====================================================================== // int main() { Vaccin v1("Zamiflu", 0.55, 200000, HighTech); Vaccin v2("Triphas", 0.20 , 10000); // affichage des vaccins à compléter ici cout << v1 << endl; cout << v2 << endl; cout << "le cout de production de v1 et v2 est : "; cout << v1.cout_production() + v2.cout_production() << endl; // Test des parties suivantes cout << "test des parties suivantes ..." << endl; // A COMPLETER return 0; }
Codez dans le fichier vaccins.cc la classe Vaccin dotée des attributs protégés suivants : son nom, le volume par dose (un double), le nombre de doses à produire (un int) et le mode de fabrication (qui peut être standard ou high tech, le type à donner est décrit plus bas).
Dotez votre classe Vaccin des méthodes publiques suivantes :
- un constructeur dont les paramètres permettent d'initialiser l'ensemble des attributs. L'attribut mode de fabrication aura Standard comme valeur par défaut (voir le type énuméré Fabrication fourni en début de fichier);
- une méthode d'affichage permettant d'afficher un vaccin selon le format suivant :
Triphas volume/dose : 0.2 nombre de doses: 10000 mode de fabrication standard
ouZamiflu volume/dose : 0.55 nombre de doses: 200000 mode de fabrication haute technologie
- une méthode conditionnement calculant le coût de conditionnement comme étant le volume par dose multiplié par le nombre de doses à produire, multiplié par COND_UNITE (une constante fournie en début de programme);
- une méthode fabrication calculant le coût de fabrication d'un vaccin. Le coût de base pour la fabrication est le volume par dose multiplié par le nombre de doses à produire, multiplié par PRIX_BASE (une constante fournie en début de programme). Si le mode de fabrication est HighTech, ce coût est majoré d'un pourcentage MAJORATION_HIGHTECH (c'est à dire coût += coût * MAJORATION_HIGHTECH) où MAJORATION_HIGHTECH est aussi une constante fournie;
- une méthode production calculant le coût de production d'un vaccin comme étant la somme des coûts de conditionnement et de fabrication.
Zamiflu volume/dose : 0.55 nombre de doses: 200000 mode de fabrication haute technologie Triphas volume/dose : 0.2 nombre de doses: 10000 mode de fabrication standard le cout de production de v1 et v2 est : 306500 test des parties suivantes ...Note : Attention à ne pas utiliser de variable locale nommée cout (pour coût), car confusion avec le flot de sortie standard.
Héritage
Notre compagnie a décidé de délocaliser la fabrication de certains vaccins.
Codez une sous-classe Delocalise de Vaccin ayant pour attribut supplémentaire un booléen indiquant si la production est délocalisée dans un pays frontalier ou non.
Dotez votre nouvelle classe des méthodes suivantes :
- un constructeur approprié
- une méthode production masquant, sans duplication de code, la méthode héritée de Vaccin.
Soit c le coût de production tel que calculé dans la classe Vaccin. Le coût de production d'un vaccin délocalisé vaudra :
- c - c * REDUC_DELOC si le vaccin est délocalisé dans un pays frontalier,
- c/2 sinon.
Pour tester votre programme, ajoutez dans le main, après le commentaire:
// Test des parties suivantesdes instructions permettant de créer les deux vaccins Delocalise suivants :
- ("Zamiflu", 0.55, 15000, HighTech) et délocalisé dans un pays qui n'est pas frontalier (stocké dans une variable v3);
- ("Triphas", 0.20, 15000, Standard) et délocalisé dans un pays frontalier (stocké dans une variable v4).
le cout de production de v3 et v4 est : 16143.8
Exercice 3 : Héritage d'un vector (niveau 2)
Programmez un classe PorteMonnaie permettant de stocker votre argent de poche.
Un PorteMonnaie ne sera rien d'autre qu'une collection de pièces (chaque pièce est un entier).
Première façon de procéder : on dote la classe PorteMonnaie d'un attribut représentant la collection (de type vector<int>).
Seconde façon: on ne met pas d'attribut pour la collection mais on fait hériter la classe PorteMonnaie de vector <int>.
C'est cette seconde option que l'on vous demande d'implémenter ici.
PorteMonnaie héritera de façon privée de vector <int>.
Vous doterez votre classe des méthodes publiques suivantes :
Vous doterez votre classe d'une méthode d'affichage (sous la forme d' une surcharge d'opérateur) permettant d'afficher le contenu du porte-monnaie (la somme des pièces contenues dans le porte-monnaie).
Pour coderez cette surcharge sans la déclarer friend de la classe.
Votre programme doit pouvoir être testé avec le programme principal suivant :
int main() { PorteMonnaie p; p.gagner(2); p.gagner(3); p.gagner(12); cout << p << endl; p.vider(); cout << p << endl; return 0; }
l'affichage produit par ce programme sera quelque chose comme :
Mon porte monnaie contient : 17 francs Mon porte monnaie contient : 0 francs
Exercice 4 : attribut statique (niveau 1)
Ouvrez le fichier ami.cc et copiez-y le code suivant :
#include <string> #include <iostream> using namespace std; // code à compléter ici int main(){ Ami a1("Toto", "Lausanne"); a1.afficher(); Ami a2(a1); a2.setVille("Brazzaville"); a2.afficher(); return 0; }
- son nom,
- la ville où il habite.
Les contraintes suivantes seront respectées :
- les attributs de votre classe devront être privés. Vous ne doterez votre classes que des "getters" et "setters" éventuellement utiles au programme principal,
- vos constructeurs/destructeurs devront afficher des messages informatifs: "Un nouvel ami" pour la construction, "Clone d'un ami" pour la construction de copie et "Sniff, fin d'une amitié" pour la destruction,
Un nouvel ami Mon ami s'appelle Toto Il habite Lausanne Clone d'un ami Mon ami s'appelle Toto Il habite Brazzaville Sniff, fin d'une amitié Sniff, fin d'une amitié
Vous souhaitez maintenant que votre classe vous permette de connaître à tout moment le nombre de vos amis habitant Lausanne (l'attribut ville vaut la chaîne de caractère "Lausanne").
- Dotez votre classe Ami d'un compteur statique d'amis habitant lausanne: nombre_ami_Lausanne;
- Mettez à jour vos constructeurs/destructeurs et toute méthode impliquée de sorte à ce que le comptage se fasse correctement;
- Initialisez ce compteur de façon appropriée.
cout << "J'ai " << Ami::nombre_ami_Lausanne << " ami(s) vivant à Lausanne" << endl;
Un nouvel ami : Mon ami s'appelle Toto Il habite Lausanne Clone d'un ami : Mon ami s'appelle Toto Il habite Brazzaville J'ai 1 ami(s) vivant à Lausanne Sniff, fin d'une amitié Sniff, fin d'une amitié
Projet : continuation
Cette semaine, vous devez commencer l'étape 2 du projet.