Bonjour,
Merci
Bonjour,
Merci
Normalement, dans le mécanisme d'héritage, la première chose à faire est d'appeler le construteur de la classe mère à l'aide de le liste d'initialisation....
Ben je sais pas trop comment t'as implementé les classes "Personnes" et "vacanciers", mais visiblement, ta fonction "achat_glace" ne fais pas partie de la classe "Personne".
Tu as deux possibilités :
1/ declarer tmp en tant que vecteur de vacanciers : vector<vacancier *> tmp;
2/ declarer un fonction virtuelle "achat_glace" dans la classe "personne" et la redefinir dans la classe "vacanciers", comme ça :
- elle fait partie de la classe "personne"
- etant virtuelle, si tu crée une instance de "vacanciers" et que tu appelles la fonction "achat_glace" sur cette instance via un pointeur de type "personne", c'est la bonne implémentation qui est appelée (celle de type "vacanciers")
La seconde solution est bien meilleure et permet de réelement tirer parti de l'héritage.
Si tu n'es pas familier avec ça, je te conseille les tutoriaux sur l'heritage et le polymorphisme.
C'est un objet Vacancier que tu crees mais tu le definis comme Personne. Vacancier derive de Personne donc un Vacancier est bien une Personne, le "cast" est autorisé. Cependant, une fois que c'est defini en Personne tu ne peux pas utiliser les methodes propres a la classe fille (Vacancier) a moins de recaster dans l'autre sens.
Remplace donc simplement cette ligne par :
Code : Sélectionner tout - Visualiser dans une fenêtre à part Vacancier * vacancier = new Vacancier();
Oui oui, c'est le polymorphisme décrit plus haut.
Lit le tuto sur le polymorphisme, c'est tres instructif !
Oui.Admettons que 10 classes héritent de Personne.
Toutes ces classes auront une méthode "achat_glace" alors que seul la classe Vacancier en a besoin.
C'est bien ce qui se passera ?
Non, c'est un objet Vacancier, mais le pointeur *vacancier pointe sur un objet de type personne. Qui ne connait donc que les méthodes de la classe "personne"Personne * vacancier = new Vacancier();
C'est un objet Personne qui est crée ?
Ben l'interet, c'est justement de pouvoir utiliser un pointeur "generique" (ici un pointeur sur un objet "personne" et qu'en fonction du type d'objet instancié (ici Vacancier) les méthodes appelées ont le même nom mais pas la meme implémentation.Je ne vois pas très bien l'intéret de mettre "achat_glace" dans la classe Personne car cette méthode ne concerne que des Vacancier.
Revoit peut-etre un peu l'architecture de tes classes. Dans la classe Personne, seul les fonctions communes doivent y figurer. Tu pourrais par exemple faire une fonction "achat(objet)" qui en fonction du type de personne et du type d'objet n'aura pas la meme fonctionnalité.
Pour ça, tu fais une classe Objet qui a tous les parametres communs (prix, poids, taille...) et une procedure du type "getObjectType"
Dans ta fonction achat (specifique à un vacancier), tu fais :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 Vacancier::achat(Objet *objet) { if (objet->getObjectType() == "glace") { ......... } if (objet->getObjectType() == "frite") { ......... } if (objet->getObjectType() == "saucisse") { ......... } if (objet->getObjectType() == "menuComplet") { ...... } }
J'oubliais....
L'interet de tout ca, c'est que dans ton code, apres tu peux faire :
Objet *pObjet = new Biere();
ou
Objet *pObjet = new Glace();
ou
Objet *pObjet = new Saucisse();
ou
Objet *pObjet = new PaireDeTonguesEnPlastiques();
et
Personne *pPersonne = new Vacancier();
ou
Personne *pPersonne = new Vendeur();
ou
Personne *pPersonne = new Nudiste();
ou
Personne *pPersonne = new Policier();
et appeler simplement :
pPersonne->achete(pObjet);
Tu auras automatiquement :
"Un Vacancier a acheté une glace"
ou
"un vendeur ne peut acheter de saucisses"
ou
"A poil les nudistes, on met pas de tongues"
ou
"Pas de biere pour les policiers pendant le service"
ou
.....
Il existe une 3eme solution.
Comme parano le dit, la methode achat_glace ne concerne que les vacanciers. En consequence elle n'a rien a faire dans la classe parente. Le polymorphisme est utile seulement si plusieurs classes filles ont besoin de methodes similaires ce qui ne semble pas etre le cas ici.
Donc la solution consiste a garder achat_glace dans Vacancier et a la sortie du vecteur de faire un dynamic_cast pour pouvoir appeler la methode de la classe fille. Si ce qui sort du vecteur n'est pas un vacancier, mais un autre type de personne, le dynamic_cast evitera les problemes.
Vacancier* vacancier = dynamic_cast<Vacancier*>(tmp[j]);
vacancier->achat_glace();
Ouais, mais le dynamic_cast, pour moi c'est un peu du bricolage...
Et achat_glace n'a rien a faire dans personne, mais je presume qu'il n'y a pas que les vacanciers qui peuvent acheter, et pas que des glaces, donc autant mettre ca dans l'architecture des le depart...
Dans ton code :
Il ne faudrait pas mieux faire
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 Vacancier* vacancier = dynamic_cast<Vacancier*>(tmp[j]); vacancier->achat_glace();
Parce que il me semble que dynamic_cast renvoit NULL si l'objet n'a pas pu etre casté. Et dans ce cas, l'appel à vacancier->achat_glace(); declenchera une exeption !
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 Vacancier* vacancier = dynamic_cast<Vacancier*>(tmp[j]); if (vacancier != NULL) vacancier->achat_glace();
Oui pardon![]()
, c'est justement ca qui protege (pouvoir verifier si le cast s'est bien passé)
Dynamic_cast n'est pas du bricolage. Il est typiquement fait pour gerer pleins d'instances de classe fille comme des instances de la classe mere jusqu'au moment ou la distinction est necessaire.
Quand je vois qu'il a un Glacier comme personne, il est peu probable que le Glacier achete quoiquecesoit (lui il vend). Donc une methode acheter n'a pas d'interet pour lui.
Ou alors il faut rajouter un niveau de classe : Creer les classes Vendeur et Acheteur derivant de la classe Personne. Puis Deriver vendeur pour creer Glacier/Boulanger et de l'autre coté deriver Acheteur en Vacanciers/Nudiste/Villageois. Dans ce cas mettre achat dans la classe Acheteur et utiliser le polymorphisme a un sens. De meme qu'on pourrait mettre vendre dans Vendeur.
Partager