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

  FORUM HardWare.fr
  Programmation
  C++

  [problème c++] Conteneur STL et héritage

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[problème c++] Conteneur STL et héritage

n°800621
Sylfurd
UUUURUTORAMAN §§
Posté le 20-07-2004 à 13:18:34  profilanswer
 

:hello:
 
Comme décrit dans mon titre j'ai un problème avec les conteneurs et l'héritage en C++ ...
 
C'est assez simple, j'ai 3 classes:
- GUIObject
- GUIObjectContainer qui hérite de GUIObject
- GUI qui hérite de GUIObjectContainer
 
Chacune de ces classes a une méthode membre void draw()
 
Je souhaite donc créer une liste STL qui contient des objets de chacune de ces classes, et appeler la méthode void draw() propre à chaque classe, avec ce simple code:
 

Code :
  1. list<GUIObject> l1;
  2.   GUI obj1;
  3.   GUIObjectContainer obj2;
  4.   l1.push_front(obj1);
  5.   l1.push_front(obj2);
  6.  
  7.   list<GUIObject>::iterator i = l1.begin();
  8.   while (i != l1.end())
  9.   {
  10.      (*i).draw();
  11.      i++;
  12.   }


 
 
Mais voila, la liste n'appelle la méthode void draw() seulement du type avec lequel elle a été initialisée :fou: !!
 
J'ai essayé, les méthodes virtuelles et les classes abstraites un peu dans tous les sens mais sans succès :sweat:
 
En java une interface aurait tout résolu, mais en c++ [:spamafote]
 
Si vous pouviez m'éclairer :jap:


Message édité par Sylfurd le 20-07-2004 à 13:32:43
mood
Publicité
Posté le 20-07-2004 à 13:18:34  profilanswer
 

n°800671
Taz
bisounours-codeur
Posté le 20-07-2004 à 14:11:59  profilanswer
 

fait un conteneur de GUIObject*. en C++ le polymorphisme passe par les pointeurs et les références

n°801140
Sylfurd
UUUURUTORAMAN §§
Posté le 20-07-2004 à 18:50:00  profilanswer
 

En effet, ça marche en déclarant void draw() virtual dans la définition de la classe GUIObjet !
 
Pour ceux que ça interresse, voila ce qu'il faut faire:

Code :
  1. list<GUIObject*> l1;
  2. GUI obj1;
  3. GUIObjectContainer obj2;
  4. l1.push_front(&obj1);
  5. l1.push_front(&obj2);
  6.    
  7. list<GUIObject*>::iterator i = l1.begin();
  8. while (i != l1.end())
  9. {
  10.      (*i)->draw();
  11.      i++;
  12. }


 
Merci :hello:


Message édité par Sylfurd le 20-07-2004 à 21:31:26
n°801150
Taz
bisounours-codeur
Posté le 20-07-2004 à 19:00:09  profilanswer
 

et les destructeurs virutels :o ? et les -> :o ?  
 
 
quant à ton exemple, il est faux. et vive foreach

n°801174
Sylfurd
UUUURUTORAMAN §§
Posté le 20-07-2004 à 19:25:08  profilanswer
 

Ah !! C'est exactement ce que je voulais, qu'on me dise que mon code n'est pas propre et pas optimisé !! Merci :jap:
 
Je me renseigne sur les destructeurs virtuels et le foreach et je resort un code plus propre :D
 
Je débarque dans la STL après avoir fait un peu de java, je regrette la doc de Java, m^me si celle de la stl n'est pas trop mal :)


Message édité par Sylfurd le 20-07-2004 à 19:32:53
n°801178
Sylfurd
UUUURUTORAMAN §§
Posté le 20-07-2004 à 19:28:34  profilanswer
 

Déjà, si je push_front pas des pointeurs çà va pas le faire, je corrige :jap:

n°801187
Taz
bisounours-codeur
Posté le 20-07-2004 à 19:50:28  profilanswer
 

tu débarques dans C++ tout cours, ça va péter, ça te faire les dents

n°801189
blackgodde​ss
vive le troll !
Posté le 20-07-2004 à 19:51:36  profilanswer
 

tu peux aussi utiliser un pointeur intelligent, ca t'evitera de faire des acrobaties pour eviter les leaks


---------------
-( BlackGoddess )-
n°801255
Sylfurd
UUUURUTORAMAN §§
Posté le 20-07-2004 à 21:03:40  profilanswer
 

Taz a écrit :

tu débarques dans C++ tout cours, ça va péter, ça te faire les dents


 
Ouais, déjà que j'en ai pas fait énormément et que je sors de 6 mois de java, c'est pas facile de ne pas mélanger ...
 
Mais en tous cas j'aimerais bien pouvoir faire un code aussi propre et clair que du java en C++ ...
 
D'ailleurs, le for_each ça à l'aire assez galère à utiliser, c'est dommage moi qui adorait le Map en Scheme, je sens que je vais garder mon while, à moins que tu ai quelque chose d'interressant à me proposer en utilisant for_each ...
 
BlackGoddess, qu'est-ce que tu entends par pointeur intelligent pour ce bout de code ?

n°801280
Sylfurd
UUUURUTORAMAN §§
Posté le 20-07-2004 à 21:31:04  profilanswer
 

Je viens de m'apercevoir du (*(*i)). :lol:
Par contre, on ne peut pas faire un espece de (i-> )-> ?? [:spamafote]
J'ai pas encore beaucoup de reflexes ... :sarcastic:


Message édité par Sylfurd le 20-07-2004 à 21:34:24
mood
Publicité
Posté le 20-07-2004 à 21:31:04  profilanswer
 

n°801341
blackgodde​ss
vive le troll !
Posté le 20-07-2004 à 22:58:29  profilanswer
 

et bien tu dois avoir un bout de code comme :
 

Code :
  1. list<GUIObject*> l;
  2. l.push_front(new GUIObjectContaine());
  3. l.push_front(new GUI());


 
tu dois faire attention car a la destruction de ta liste, les objets qu'elle contientse seront pas détruit. ce problème potentiel peut être résolu par l'utilisation d'un pointeur intelligent comme boost::shared_ptr (je ne sais pas si c'est le plus approprié). Il permet de détruire l'objet automatiquement à la destruction du dernier pointeur vers lui. Ainsi, la destruction de ta liste détruira les pointeurs qui détruiront automatiquement les objets.


---------------
-( BlackGoddess )-
n°802311
Sylfurd
UUUURUTORAMAN §§
Posté le 21-07-2004 à 19:01:35  profilanswer
 

Ok, merci, je ne connaissais pas, j'entends de plus en plus parler de boost aussi, faudrait que je me renseigne dessus :jap:

n°802783
el muchach​o
Comfortably Numb
Posté le 22-07-2004 à 09:53:38  profilanswer
 

Sylfurd a écrit :


Mais en tous cas j'aimerais bien pouvoir faire un code aussi propre et clair que du java en C++ ...


Faut pas rêver là...
Le c++, c'est puissant, mais pour la propreté et la clarté, tu peux laisser tomber.


---------------
Les aéroports où il fait bon attendre, voila un topic qu'il est bien
n°802988
Taz
bisounours-codeur
Posté le 22-07-2004 à 12:18:22  profilanswer
 

c'est petit ça de profiter des débutants pour tirer des conclusions

n°804294
Sylfurd
UUUURUTORAMAN §§
Posté le 23-07-2004 à 12:37:07  profilanswer
 

el muchacho a écrit :

Faut pas rêver là...
Le c++, c'est puissant, mais pour la propreté et la clarté, tu peux laisser tomber.


 
C'est clair que c'est mal barré, mais en essayant de structurer mon code comme en Java, il est bien plus clair et organisé que les précédents :)
 
En tous cas il avance vite et bien :jap:


Message édité par Sylfurd le 23-07-2004 à 12:38:33
n°804344
antsite
Je me souviens
Posté le 23-07-2004 à 13:12:55  profilanswer
 

el muchacho a écrit :

Faut pas rêver là...
Le c++, c'est puissant, mais pour la propreté et la clarté, tu peux laisser tomber.


 
regarde le code de Taz, et tu verras que c'est pas le code mais le développeur qui est en cause dans bien des cas...  :non:


Message édité par antsite le 23-07-2004 à 13:13:07
n°804395
panic_defe​nce
Posté le 23-07-2004 à 13:48:09  profilanswer
 

Sylfurd a écrit :

Je viens de m'apercevoir du (*(*i)). :lol:
Par contre, on ne peut pas faire un espece de (i-> )-> ?? [:spamafote]
J'ai pas encore beaucoup de reflexes ... :sarcastic:


 
nop d'après ce que j'ai pu constater tu ne peut pas faire:
 
i->foo ();
 
i n'est pas un pointeur vert ton objet, (*i) marche parce que la fonction * a etait surdefinie si mes souvenir son bon i->first est l'element en question et c'est equvalent a (*i)
 
bref dans son cas (i->first)->draw () doit marcher :D


---------------
We are Penguin. Resistance is futile. You will be assimilated
n°804931
Sylfurd
UUUURUTORAMAN §§
Posté le 23-07-2004 à 20:24:46  profilanswer
 

panic_defence a écrit :

nop d'après ce que j'ai pu constater tu ne peut pas faire:
 
i->foo ();
 
i n'est pas un pointeur vert ton objet, (*i) marche parce que la fonction * a etait surdefinie si mes souvenir son bon i->first est l'element en question et c'est equvalent a (*i)
 
bref dans son cas (i->first)->draw () doit marcher :D


 
Ok, ça me semble logique :jap:

n°804932
Taz
bisounours-codeur
Posté le 23-07-2004 à 20:26:20  profilanswer
 

parenthèse en trop

n°804985
Taz
bisounours-codeur
Posté le 23-07-2004 à 21:27:02  profilanswer
 

Code :
  1. #include <iostream>
  2. class GUIObject
  3. {
  4. public:
  5.   virtual void draw() = 0;
  6.   virtual ~GUIObject() { }
  7. };
  8. class Button
  9.   : public GUIObject
  10. {
  11. public:
  12.   virtual void draw()
  13.   {
  14.     std::cout << "Push me\n";
  15.   }
  16.   virtual ~Button () { }
  17. };
  18. class Dialog
  19.   : public GUIObject
  20. {
  21. public:
  22.   virtual void draw()
  23.   {
  24.     std::cout << "Talk to me\n";
  25.   }
  26.   virtual ~Dialog () { }
  27. };
  28. namespace
  29. {
  30.   template<typename T>
  31.   inline void kknd(T begin, T end)
  32.   {
  33.     while(begin != end)
  34.       {
  35. delete *begin++;
  36.       }
  37.   }
  38. }
  39. #include <algorithm>
  40. #include <list>
  41. int main()
  42. {
  43.   std::list<GUIObject *> container;
  44.   container.push_back( new Button );
  45.   container.push_back( new Dialog );
  46.   std::for_each(container.begin(), container.end(),
  47.  std::mem_fun(&GUIObject::draw));
  48.   kknd(container.begin(), container.end());
  49. }


 
et comme déjà dit, faut aller chez boost pour des shared_ptr digne de ce nom et trouver de vrais wrapper pour tout ce qui mem_fun, ptr_fun, bind, etc

n°805041
Sylfurd
UUUURUTORAMAN §§
Posté le 23-07-2004 à 22:57:13  profilanswer
 

Interressant tout ça !!!!
Et si la fonction appliquée avec for_each contient des paramètres ?
 
Sinon, qu'est-ce que le for_each apporte de plus que que le le while ? Plus rapide ? Plus propre ?
 
En tous cas merci beaucoup, t'es un chef :D

n°805104
Taz
bisounours-codeur
Posté le 24-07-2004 à 00:49:40  profilanswer
 

c'est générique, déjà écrit, propre, réutilisable.
 
si ta fonction doit être appelé avec des paramètre, il y a tout ce qu'il faut dans STL et boost

n°805845
Sylfurd
UUUURUTORAMAN §§
Posté le 25-07-2004 à 20:37:21  profilanswer
 

:sweat:
 
J'ai voulu séparer les définitions des Méthodes de leur déclarations (bah oui je voulais tout faire comme en Java mais ça pose des problèmes en c++) mais maintenant ça marche plus :sweat: Il trouve pas les définitions ...
 
Aarfff j'aime pas perdre du temps comme ça, surtout que je suis sur que c'est un petit oubli quelque part :fou:
 
bon, je continue mes recherches :o

n°805851
Taz
bisounours-codeur
Posté le 25-07-2004 à 20:44:14  profilanswer
 

ben s'il trouve pas la définition c'est que tu compiles pas le fichier. même problème en java

n°805854
Sylfurd
UUUURUTORAMAN §§
Posté le 25-07-2004 à 20:49:42  profilanswer
 

Bon, j'ai mis les définitions des méthodes juste en dessous des de la définition de la classe et non pas dans 2 fichiers séparés...
 
Premier problème: il fallait pas définir les méthodes virtuelles en dehors des classes :sarcastic: ...
 
Comme ça, ça foncitonne, je vais essayer de mettre les définitions dans un .cpp :) ...

n°805857
Sylfurd
UUUURUTORAMAN §§
Posté le 25-07-2004 à 20:52:33  profilanswer
 

Taz a écrit :

ben s'il trouve pas la définition c'est que tu compiles pas le fichier. même problème en java


 
Bon apparemment tu as raison, je viens de fire la m^me constatation :) Je sais d'où ça vient en plus :D
 
Merci pour l'aide rapide ;)
 
Bon, j'ai plus qu'à apprendre comment compiler correctement avec gcc et pas recopier bêtement le log de Dev-CPP :ange:


Message édité par Sylfurd le 25-07-2004 à 21:01:00
n°805869
_momone_
Posté le 25-07-2004 à 21:15:54  profilanswer
 

Taz> Pourquoi tu as mis la fonction kknd dans un namespace?
 
Sinon Sylfurd, tu devrais mettre les définitions des membres de tes classes dans un fichier .cpp et uniquement la déclaration dans les headers (.h). Il ne faut pas tout mettre dans les headers.
Et puis les méthodes virtuelles peuvent être définies "en dehors" des classes. Tu peux très bien faire un:
int MaClasse::MaFonction()
{
}
même si MaFonction est virtuelle.


Message édité par _momone_ le 25-07-2004 à 21:17:14
n°805875
Sylfurd
UUUURUTORAMAN §§
Posté le 25-07-2004 à 21:23:48  profilanswer
 

Apparement gcc n'avait pas aimé, mais le problème pouvait venir d'autre part, m^me si le message d'erreur semblait asses parlant...
 
Dès que je comprends comment compiler tout seul avec gcc, je sépare les définitions des méthodes de leur déclaration :jap:

n°805893
Taz
bisounours-codeur
Posté le 25-07-2004 à 22:08:55  profilanswer
 

parce que krush, kill 'n destroy n'était destinée qu'à un usage local.

n°805959
Sylfurd
UUUURUTORAMAN §§
Posté le 26-07-2004 à 00:07:23  profilanswer
 

En fait tu a tout à fait raison momone à propos des méthodes virtuelles :)
 
Bon, ça marche à peu près à part les variables globales, gcc trouve qu'elles sont non déclarées quand je les utilise dans une classe séparée en fichiers cpp et h [:spamafote] Je c'est que c'est pas bien les variables globales :whistle: mais elles ne sont que temporaires :o
 
Edit: Compilation finished at Mon Jul 26 00:47:48  :D


Message édité par Sylfurd le 26-07-2004 à 00:48:04
n°805968
Sylfurd
UUUURUTORAMAN §§
Posté le 26-07-2004 à 00:43:07  profilanswer
 

C'est bon, j'ai résolu mon problème de variable globale, il suffit de déclarer la variable en tant qu'externe avec le mot clé extern !!
 
Ca fait plaisir, je peux enfin aller dormir !!!

mood
Publicité
Posté le   profilanswer
 


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

  [problème c++] Conteneur STL et héritage

 

Sujets relatifs
système de langue (problème avec les url !)Probleme avec variable/sql et cache opera
[Résolu] Probleme de résolutin de code html ecrit avec du php par echoproblème authentification proxy
Problème avec "Redim Preserve"Gkt2-perl: problème avec les combobox
Problème de pourcentage pour les balises div[css] class, id et heritage
probleme datagridProblème de date dans requête imbriquée
Plus de sujets relatifs à : [problème c++] Conteneur STL et héritage


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