Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1918 connectés 

  FORUM HardWare.fr
  Programmation
  C++

  Héritage de classe et vector

 


 Mot :   Pseudo :  
 
 Page :   1  2  3
Page Précédente
Auteur Sujet :

Héritage de classe et vector

n°586123
Profil sup​primé
Posté le 09-12-2003 à 00:08:57  answer
 

Alors une petite question surement conne mais ca coute rien de la poser...
 
Disons que j'ai 3 classes:
 
- une classe "animal" qui est la classe de base
- une classe "chat" qui hérite de "animal" et lui ajoute de nouvelles choses, etc...
- une classe "tortue" qui hérite aussi de "animal", etc...
 
Alors disons qu'ensuite je veux classer tout mes chats et mes tortues dans un "vector", je fais comment et est-ce possible ???
 
Parce que j'ai testé :
 

Code :
  1. vector<animal> listeanimaux;


 
Avec des push_back() on arrive à ajouter les animaux dans la liste, par contre lorsque je veux accéder aux propriétés ou méthodes, seules celles hérités de "animal" sont disponibles...
 
 

mood
Publicité
Posté le 09-12-2003 à 00:08:57  profilanswer
 

n°586135
marmotte.t​ranquille
Posté le 09-12-2003 à 00:16:16  profilanswer
 

Je vais sans doute dire une grosse connerie :
un "cast" explicite, ça ne marche pas ?

n°586143
Taz
bisounours-codeur
Posté le 09-12-2003 à 00:19:46  profilanswer
 

std::vector<animal*>
 
en C++, le polymorphisme passe par les pointeurs ou les références.
 
 
mais c'est quoi cette psychose des casts, c'est les fêtes qui vous font ça ou quoi? déjà que vous castez quand c'est inutile, voulez caster quand on ne peut pas. réfléchissez une peu sur ce que ça veut dire "caster" et pensez au types.

n°586144
Profil sup​primé
Posté le 09-12-2003 à 00:19:47  answer
 

Non j'ai essayé et puis j'y tiens pas trop au "cast" ca va être plus que crade si il faut que je caste à chaque fois que je veux lire une propriété qui n'est pas dans "animal"

n°586148
Taz
bisounours-codeur
Posté le 09-12-2003 à 00:21:44  profilanswer
 

ben y a pas besoin de cast
 
 
si  
*v[0] est un chien, et *v[1] un chat
 
v[0]->crie() -> "Ouaf"
v[1]->crie() -> "Miaou"

n°586154
Profil sup​primé
Posté le 09-12-2003 à 00:25:17  answer
 

Taz a écrit :

ben y a pas besoin de cast
 
 
si  
*v[0] est un chien, et *v[1] un chat
 
v[0]->crie() -> "Ouaf"
v[1]->crie() -> "Miaou"


 
je comprends pas ca passe pas, en fait j'ai une propriété "taille" qui n'éxiste que dans la classe "tortue" et pas dans "chien" ni "animal" et je n'arrive pas à y accéder...

n°586156
Taz
bisounours-codeur
Posté le 09-12-2003 à 00:26:36  profilanswer
 

ben là il faut caster vie un dynamic_cast. si tu utilises des propriétés personnelle à la tortue, il faut que ton objet soit une tortue et typé tel quel

n°586162
Profil sup​primé
Posté le 09-12-2003 à 00:29:30  answer
 

Taz a écrit :

ben là il faut caster vie un dynamic_cast. si tu utilises des propriétés personnelle à la tortue, il faut que ton objet soit une tortue et typé tel quel


 
Ok donc ca semble assez bancal comme facon de faire...
 
Comment ferais-tu pour classer dans un tableau des objets qui sont hérités de la même classe de base mais dont certaines propriétés ou méthodes sont personnelles et sans que cela soit trop infame comme solution ?

n°586176
Taz
bisounours-codeur
Posté le 09-12-2003 à 00:36:04  profilanswer
 

ça l'est pas du tout !
si tu fais de la généricité, tu considères des propriétés génériques, si tu veux quelque chose de spécifique, il faut retrouver cette spécifité.
 
L'exemple célèbre de Stroustrup, c'est les Saab : une 900 et une 90 : un voiture et un avion. c'est des Saab, pas de problèmes, y a des propriétés commune. Maintenant, si tu prends la peine de t'assurer que telle Saab est bien une voiture, je te laisse imaginer ce qui se passe tu tente de la faire décoler

n°586187
Profil sup​primé
Posté le 09-12-2003 à 00:40:42  answer
 

Taz a écrit :

ça l'est pas du tout !
si tu fais de la généricité, tu considères des propriétés génériques, si tu veux quelque chose de spécifique, il faut retrouver cette spécifité.
 
L'exemple célèbre de Stroustrup, c'est les Saab : une 900 et une 90 : un voiture et un avion. c'est des Saab, pas de problèmes, y a des propriétés commune. Maintenant, si tu prends la peine de t'assurer que telle Saab est bien une voiture, je te laisse imaginer ce qui se passe tu tente de la faire décoler


 
Ok bon tant que ca te semble bien alors pourquoi pas ;)  
 
Je vais essayer de voir ca d'un peu plus près, merci.

mood
Publicité
Posté le 09-12-2003 à 00:40:42  profilanswer
 

n°586202
marmotte.t​ranquille
Posté le 09-12-2003 à 01:34:14  profilanswer
 

Taz a écrit :

ben là il faut caster vie un dynamic_cast. si tu utilises des propriétés personnelle à la tortue, il faut que ton objet soit une tortue et typé tel quel


 
:whistle:


Message édité par marmotte.tranquille le 09-12-2003 à 01:48:57
n°586205
Taz
bisounours-codeur
Posté le 09-12-2003 à 01:53:15  profilanswer
 

oui ?

n°586206
marmotte.t​ranquille
Posté le 09-12-2003 à 01:55:31  profilanswer
 

Et la psychose des cast :o

n°586207
Taz
bisounours-codeur
Posté le 09-12-2003 à 02:01:30  profilanswer
 

...

n°586892
blackgodde​ss
vive le troll !
Posté le 09-12-2003 à 21:07:04  profilanswer
 

rajoute un membre à ta classe qui indique le type, pour retrouver tes spécialités
 

Code :
  1. struct animal
  2. {
  3.   enum type_animal
  4.   {
  5.     type_chien,
  6.     ...
  7.   } type;
  8. };
  9. class chien : public animal
  10. {
  11.   chien()
  12.   : type(type_chien)
  13.   {
  14.   }
  15.   void aboie()
  16.   {
  17.   }
  18. };
  19. int main()
  20. {
  21.   vector<animal> animaux;
  22.   // remplissage
  23.   if(animaux[0]->type == animal::type_chien)
  24.   {
  25.     (dynamic_cast<chien*>(animaux[0]))->aboie();
  26.   }
  27.   return 0;
  28. }


---------------
-( BlackGoddess )-
n°586893
Taz
bisounours-codeur
Posté le 09-12-2003 à 21:09:03  profilanswer
 

BlackGodess > droit dans le mur ! si on a inventé les RTTi, c'est justement pour pas avoir à écrire de genre de chose.
 
devine quoi, si le dynamic_cast<chien*> échoue, c'est àd ire que animaux[i] n'est pas une sort de chien, et bien le résultat vaut 0 (NULL) magique ?

n°586895
blackgodde​ss
vive le troll !
Posté le 09-12-2003 à 21:10:20  profilanswer
 

ah ? j'avais vu qu'il y avait une sécuritée supplémentaire entre le dynamic_cast et le static_cast, mais c'est donc a l'execution ?
 
bien, désolé pour les anneries :(


---------------
-( BlackGoddess )-
n°586896
Taz
bisounours-codeur
Posté le 09-12-2003 à 21:13:01  profilanswer
 

static_cast -> transtypage sur, fonctionnel à la compilation, pas d'erreur. du genre chien* -> animal*
 
dynamic_cast -> non sur, nécessite des information de types dynamique, genre animal* -> chien* (et oui, impossible de savoir à la compilation si un animal est effectivement un chien). évidemment, on peut vérifier la réussite du transtypage, sinon ça n'a pas d'intéret)

n°586911
blackgodde​ss
vive le troll !
Posté le 09-12-2003 à 21:49:35  profilanswer
 

bien, merci :jap:


---------------
-( BlackGoddess )-
n°587055
Profil sup​primé
Posté le 10-12-2003 à 02:56:55  answer
 

Merci pour ces précisions ...

n°587056
Taz
bisounours-codeur
Posté le 10-12-2003 à 02:59:35  profilanswer
 

dis le si tu t'en sors pas

n°588809
iraysyvalo
Posté le 11-12-2003 à 23:41:50  profilanswer
 

Taz a écrit :

BlackGodess > droit dans le mur ! si on a inventé les RTTi, c'est justement pour pas avoir à écrire de genre de chose.
 
devine quoi, si le dynamic_cast<chien*> échoue, c'est àd ire que animaux[i] n'est pas une sort de chien, et bien le résultat vaut 0 (NULL) magique ?  


 
Taz, donc dans ce cas, il faudrait d'abord faire un test prealable quand meme sur le dynamic_cast non ??
 
Style  

Code :
  1. chien* toutou= (dynamic_cast<chien*>(animaux[0]));
  2. if (0!=toutou) // Ouarf, c'est un toutou finalement
  3.    toutou->aboie();


 
Il y a plus elegant ?


Message édité par iraysyvalo le 11-12-2003 à 23:42:29
n°588810
Taz
bisounours-codeur
Posté le 11-12-2003 à 23:44:37  profilanswer
 

moi je trouve pas si moche que ça (sauf tes parenthèse superflues)
évidemment, si on travaille avec des références, le try/catch est plus attractif.

n°588815
Taz
bisounours-codeur
Posté le 11-12-2003 à 23:51:10  profilanswer
 

tu peux faire comme ça sinon

Code :
  1. if(Dog *d = dynamic_cast<Dog*>(catsndogs[i]))
  2. {
  3.   d->bite();
  4. }

n°590080
iraysyvalo
Posté le 13-12-2003 à 19:42:44  profilanswer
 

Toujours une histoire d'animaux .. polymorphiques ?? ;)
 
Supposons que je veuille reconstruire un animal a partir de son etat-civil qui va donc m'indiquer si c'est une tortue, un chien ou un chat.
 
Comment construire un objet du bon type a la volee ?
Quelle est la bonne architecture ?
 
Ma piste: avoir une fonction de reconstruction virtuelle dans Animal, et profiter du polymorphisme ... mais je bloque.

n°590081
Taz
bisounours-codeur
Posté le 13-12-2003 à 19:44:49  profilanswer
 

une grosse fonction avec un méga swith qui renvoie un pointeur Animal* vers la nouvelle bébette alouée dynamiquement.
cette fonction peut etre une fonction membre statique auquel cas elle est appelé « fabrique »

n°590104
iraysyvalo
Posté le 13-12-2003 à 20:20:24  profilanswer
 

Ce serait  
 
static Animal* Animal::fabrique(){ ?
   
.... mais si ce qu'on construit est, par exemple, un Chat, ca va pas etre bon vu que les Chats et les Chiens derivent d'Animal et ne sont pas encore connus ...  
 

n°590108
Taz
bisounours-codeur
Posté le 13-12-2003 à 20:24:50  profilanswer
 

avec un paramètre quand même.
tu fais une fabrique dans Animal si tu connais déjà certaines sous-classes, évidemment.

n°590117
iraysyvalo
Posté le 13-12-2003 à 20:35:41  profilanswer
 


Apres essai :

Code :
  1. // fichier Animal.h
  2. // Forward declaration don't work
  3. // Put the two includes instead in Animal.cpp
  4. // fichier Chien.h
  5. #include "Animal.h"


 
Et apres pour implementer fabrique dans Animal, comme ceci ??

Code :
  1. static Animal* Animal::fabrique(Etatcivil etat){
  2.    Animal *bete;
  3.    switch(etat.nature){
  4.       case CHIEN:
  5.           // preparer le chien puis ..
  6.          return dynamic_cast<Chien*> (bete);
  7.    }
  8. }


Message édité par iraysyvalo le 14-12-2003 à 05:38:12
n°590118
Taz
bisounours-codeur
Posté le 13-12-2003 à 20:37:11  profilanswer
 

ben non
 
return new Chien;


Message édité par Taz le 13-12-2003 à 20:37:26
n°590121
iraysyvalo
Posté le 13-12-2003 à 20:38:27  profilanswer
 

Et l'appel serait donc  
 

Code :
  1. Animal *bete= Animal::fabrique(etat);
  2. // et un peu plus tard
  3. if(Chien *d = dynamic_cast<Chien*> bete){
  4.   d->attaque();
  5. }


Message édité par iraysyvalo le 13-12-2003 à 22:30:01
n°590124
schnapsman​n
Zaford Beeblefect
Posté le 13-12-2003 à 20:41:58  profilanswer
 

iraysyvalo a écrit :


Ca marche comme ca ? Viens que je t'embrasse Taz ..


 
Et oui, un chien est un animal. Contrairement à un animal qui n'est pas forcément un chien, capiche?


---------------
From now on, you will speak only when spoken to, and the first and last words out of your filthy sewers will be "Sir!"
n°590125
Taz
bisounours-codeur
Posté le 13-12-2003 à 20:42:46  profilanswer
 

SchnapsMann a écrit :


 
Et oui, un chien est un animal. Contrairement à un animal qui n'est pas forcément un chien, caniche?

n°590127
schnapsman​n
Zaford Beeblefect
Posté le 13-12-2003 à 20:43:18  profilanswer
 


[:lorill]


Message édité par schnapsmann le 13-12-2003 à 20:43:24

---------------
From now on, you will speak only when spoken to, and the first and last words out of your filthy sewers will be "Sir!"
n°590138
iraysyvalo
Posté le 13-12-2003 à 20:54:40  profilanswer
 


La suite d'appels precedente marche ?

n°590191
schnapsman​n
Zaford Beeblefect
Posté le 13-12-2003 à 22:17:21  profilanswer
 

iraysyvalo a écrit :


La suite d'appels precedente marche ?


si animal peut attacker, alors chien le peut  :o


---------------
From now on, you will speak only when spoken to, and the first and last words out of your filthy sewers will be "Sir!"
n°590197
iraysyvalo
Posté le 13-12-2003 à 22:29:38  profilanswer
 


Erreur typographique .. j'edite ..

n°590314
iraysyvalo
Posté le 14-12-2003 à 04:55:27  profilanswer
 


Edit du code d'avant


Message édité par iraysyvalo le 14-12-2003 à 04:56:27
n°590317
nraynaud
lol
Posté le 14-12-2003 à 08:30:00  profilanswer
 

Taz a écrit :

ben là il faut caster vie un dynamic_cast. si tu utilises des propriétés personnelle à la tortue, il faut que ton objet soit une tortue et typé tel quel

Pattern 1) Expert : celui qui a l'information s'occupe du traitement. Si tu n'as pas l'information alors ce n'est pas à toi de faire le traitement.
 
En l'occurence, dans cette situation on utilise un Visiteur.


---------------
trainoo.com, c'est fini
n°590332
nraynaud
lol
Posté le 14-12-2003 à 10:22:09  profilanswer
 

Code :
  1. #include<iostream>
  2. using namespace std;
  3. class Animal;
  4. class Chien;
  5. class Chat;
  6. class VisiteurAnimalier;
  7. class Animal {
  8. public :
  9.         virtual string bruit() = 0;
  10. virtual void accepte(VisiteurAnimalier &vis) = 0;
  11.        
  12. };
  13. class FabriqueDAnimaux {
  14. public :
  15.     virtual Animal *creeAnimal() = 0;
  16. };
  17. class VisiteurAnimalier {
  18. public :
  19.     virtual void visiteChien(Chien *lechien) = 0;
  20.     virtual void visiteChat(Chat *lechat) = 0;
  21.     virtual ~VisiteurAnimalier() = 0;
  22. };
  23. class Chien : Animal {
  24.     class FabriqueDeChien : FabriqueDAnimaux {
  25.     public :
  26.         virtual Animal *creeAnimal() {
  27.             return new Chien();
  28.         };
  29.     };
  30.    
  31. public :
  32.     static const FabriqueDeChien *fabrique;
  33.    
  34.     virtual string bruit() {
  35.         return "OUAF";
  36.     }
  37.     void accepte(VisiteurAnimalier &vis) {
  38.         vis.visiteChien(this);
  39.     }
  40.     // ça connerie à lui
  41.     void mordre() {
  42.         cout << "je luis mords le mollet" << endl;
  43.     }
  44. };
  45. class Chat : Animal {
  46.     class FabriqueDeChat : FabriqueDAnimaux {
  47.     public :
  48.         virtual Animal *creeAnimal() {
  49.             return new Chat();
  50.         };
  51.     };
  52. public :   
  53.     static const FabriqueDeChat *fabrique;
  54.    
  55.     virtual string bruit() {
  56.         return "Miaou";
  57.     }
  58.     virtual void accepte(VisiteurAnimalier &vis) {
  59.         vis.visiteChat(this);
  60.     }
  61.    
  62.     // la connerie que lui seul peut faire
  63.     void grimperArbre() {
  64.         cout << "je grimpe et je suis trop con pour redescendre" << endl;
  65.     }
  66. };
  67. class VisiteurDeconneur : VisiteurAnimalier {
  68. public :
  69.     ~VisiteurDeconneur();
  70.     virtual void visiteChien(Chien *lechien) {
  71.         lechien->mordre();
  72.     };
  73.     virtual void visiteChat(Chat *lechat) {
  74.         lechat->grimperArbre();
  75.     };
  76. };
  77. const Chat::FabriqueDeChat *Chat::fabrique = new FabriqueDeChat();
  78. const Chien::FabriqueDeChien *Chien::fabrique = new FabriqueDeChien();


(j'imagine que Taz corrigera ce qui lui plait pas)
 
voilà l'esprit de tous les services que tu veux, en version bien typée et propre.
Il y a un Pattern Fabrique Abstraite (classe dont les instances sont des usines à instances) l'intérêt est de pouvoir fabriquer des animaux "à l'aveuglette", imagine par exemple un monde un peu crado où pour avoir un animal de compagnie on doive acheter un jeton pui passer le jeton à l'Administration qui va lui fabriquer le chien et l'enregistrer légalement par la même occasion. Le jeton contiendra une référence à la Fabrique idoine, mais le fonctionnaire ne saura pas quel annimal sera créé (il s'en fout).  
C'est pas top comme exemple, mais je vois pas à quoi pourrait te servir ta fabrique dans ton modèle.
 
Pour les traitements spécifique par animal, il y a tout le système de Visiteur, un objet qui a un traitement spécifique par animal est un VisiteurAnimalier (qui ne modélise pas une personne mais un trait de personnalité d'un objet).
 
Au passage, j'ai mis les fabriques en Singleton, c'est-à-dire qu'il n'existe qu'une seule instance de la classe FabriqueDeChat accessible dans la classe.


---------------
trainoo.com, c'est fini
mood
Publicité
Posté le   profilanswer
 

 Page :   1  2  3
Page Précédente

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C++

  Héritage de classe et vector

 

Sujets relatifs
Probleme d'heritage et de surcharge en C#passage de std::string (ou std::vector<char>) à bit_vector (ou bitset)
Source de la classe LoginContexttype contenu ds un vector
VB + Classe - Tableau d'objet[Java] interface: heritage de methodes statiques
Comment se servir dans une classe d'une fonction menbre d'une autre?[Java]Appeler une méthode d'une classe à partir d'1 String [Résolu]
Comment inclure une classe dans une autre?Gestion d'une variable de classe
Plus de sujets relatifs à : Héritage de classe et vector


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR