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

  FORUM HardWare.fr
  Programmation
  C++

  Ou placer un virtual operator== ?

 


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

Ou placer un virtual operator== ?

n°713553
Slayne
Yaouchhh
Posté le 01-05-2004 à 16:04:31  profilanswer
 

Bonjour,
 
Je suis novice en C++, et je suis confronté à un problème dont pour l'instant je ne connais pas la solution.
 
J'ai pour habitude de redefinir mes operator +, *, == à l'extérieur de ma classe, dans un autre fichier (operateurs.cpp par exemple) en mettant les fonctions operator en friend.
 
Mais voila, je souhaite qu'un operator== soit virtual, car je veux le redéfinir dans les sous classes. Mais il est impossible que mon friend bool operator==(...) devienne virtual, une fonction friend ne pouvant etre virtual.
 
Quelle est la solution la plus propre pour résoudre ça ?
Merci d'avance :)

mood
Publicité
Posté le 01-05-2004 à 16:04:31  profilanswer
 

n°713555
xterminhat​e
Si vis pacem, para bellum.
Posté le 01-05-2004 à 16:08:45  profilanswer
 

Fait voir ta classe de base qui contient un opérateur... C'est pas clair ton histoire.
 
Tu peux ecrire ca...
 

Code :
  1. class deBase
  2. {
  3. virtual deBase operator* ( const deBase & );
  4. };
  5. class Heritee : public deBase
  6. {
  7. virtual Heritee operator* ( const Heritee & );
  8. };


Message édité par xterminhate le 01-05-2004 à 16:10:59

---------------
Cordialement, Xterm-in'Hate...
n°713564
Slayne
Yaouchhh
Posté le 01-05-2004 à 16:20:13  profilanswer
 

Pour reprendre ton exemple, le probleme c'est que je définis toujours mes operateurs externes comme ca :
 

Code :
  1. class deBase
  2. {
  3. friend deBase operator* ( const deBase &, const deBase & );
  4. };


 
 
pour ensuite les définir dans un fichier à part, operateurs.cpp par exemple.
Mais il devient impossible de les rendre virtual du coup, ce qui est génant vu que je redéfini ces opérateurs dans les classes Héritées. :/
 
(hum j'ai l'impression d'avoir réécris la meme chose, donc c'est peut etre pas plus clair  [:guts] )
 
Mais bon effectivement je peux tout réécrire comme ça, mais est ce vraiment une bonne solution ? (c'est peut etre la seule ..)


Message édité par Slayne le 01-05-2004 à 16:21:05
n°713565
Taz
bisounours-codeur
Posté le 01-05-2004 à 16:20:38  profilanswer
 

je pense pas que ça soit très sain de faire des opérateurs virtuels, encore moins les binaires

n°713566
xterminhat​e
Si vis pacem, para bellum.
Posté le 01-05-2004 à 16:22:43  profilanswer
 

Désolé, mais je ne comprends pas ce que tu veux faire. Rendre virtuel des opérateurs n'est pas une finalité e nsoi. As tu vraiment les idées claires en terme de programmation objet ?


---------------
Cordialement, Xterm-in'Hate...
n°713574
Slayne
Yaouchhh
Posté le 01-05-2004 à 16:34:22  profilanswer
 

Bon d'accord je prend un exemple qui j'espere sera plus clair.
 
Comme classe mère, je prend une classe abstraite Forme.

Code :
  1. class Forme
  2. {
  3. public :
  4. friend operator==(const Forme &,const Form & );
  5. protected :
  6. Point centre;
  7. }


 
Son operator== retournera true si le centre des 2 Formes est le meme.
 
Les classes qui hériteront de Forme seront Carré,Cercle, Triangle, etc.
Par exemple Cercle :
 

Code :
  1. class Cercle : public Forme
  2. {
  3. public :
  4. friend bool operator==(const Carre &,const Carre & );
  5. private :
  6. double rayon;
  7. }


 
Si je fais un :
Cercle c1(Point(0,0),2);
Cercle c2(Point(0,0),3);
c1 == c2;
Il n'y aura aucun soucis, ca retournera false, les 2 cercles n'ont pas le meme rayon.
 
en revanche, un :
Forme *c3 = new Cercle(c1);
Forme *c4 = new Cercle(c2);
(*c3) == (*c4);
Ca retournera vrai vu que ce sera operator== de Forme qui sera appelé.
 
J'espere avoir été plus clair cette fois ci  :)


Message édité par Slayne le 01-05-2004 à 16:35:31
n°713578
Taz
bisounours-codeur
Posté le 01-05-2004 à 16:37:40  profilanswer
 

les friend cai mal

n°713579
Taz
bisounours-codeur
Posté le 01-05-2004 à 16:39:03  profilanswer
 

Code :
  1. #include <iostream>
  2. struct Base
  3. {
  4.   virtual ~Base()
  5.   { }
  6.   virtual bool less(const Base &other) const =0;
  7. };
  8. struct Foo
  9.   : public Base
  10. {
  11.   bool less(const Foo &other) const
  12.   {
  13.     std::cout << "bool Foo::less(const Foo &other) const\n";
  14.     return this < &other;
  15.   }
  16.   virtual bool less(const Base &other) const
  17.   {
  18.     std::cout << "bool Foo::less(const Base &other) const\n";
  19.     return less(dynamic_cast<const Foo &>(other));
  20.   }
  21. };
  22. struct Bar
  23.   : public Base
  24. {
  25.   bool less(const Bar &other) const
  26.   {
  27.     std::cout << "bool Bar::less(const Bar &other) const\n";
  28.     return this < &other;
  29.   }
  30.   virtual bool less(const Base &other) const
  31.   {
  32.     std::cout << "bool Bar::less(const Base &other) const\n";
  33.     return less(dynamic_cast<const Bar &>(other));
  34.   }
  35. };
  36. inline bool operator<(const Base &lhs, const Base &rhs)
  37. {
  38.   std::cout << "bool operator<(const Base &lhs, const Base &rhs)\n";
  39.   return lhs.less(rhs);
  40. }
  41. inline bool operator<(const Foo &lhs, const Foo &rhs)
  42. {
  43.   std::cout << "bool operator<(const Foo &lhs, const Foo &rhs)\n";
  44.   return lhs.less(rhs);
  45. }
  46. inline bool operator<(const Bar &lhs, const Bar &rhs)
  47. {
  48.   std::cout << "bool operator<(const Bar &lhs, const Bar &rhs)\n";
  49.   return lhs.less(rhs);
  50. }
  51. int main()
  52. {
  53.   Base *b1, *b2;
  54.   Foo f1, f2;
  55.   Bar g1, g2;
  56.   std::cout << "Foo < Foo\n";
  57.   f1 < f2;
  58.   std::cout << '\n';
  59.   std::cout << "Bar < Bar\n";
  60.   g1 < g2;
  61.   std::cout << '\n';
  62.   b1 = &f1;
  63.   b2 = &f2;
  64.   std::cout << "Base& < Base& -> Foo < Foo\n";
  65.   *b1 < *b2;
  66.   std::cout << '\n';
  67.   b1 = &g1;
  68.   b2 = &g2;
  69.   std::cout << "Base& < Base& -> Bar < Bar\n";
  70.   *b1 < *b2;
  71.   std::cout << '\n';
  72.  
  73.   b1 = &f1;
  74.   b2 = &g1;
  75.   try
  76.     {
  77.       std::cout << "Base& < Base& -> Foo < Bar\n";
  78.       *b1 < *b2;
  79.     }
  80.   catch(std::bad_cast &ex)
  81.     {
  82.       std::cout.flush();
  83.       std::cerr << "Failed " << ex.what() << '\n';
  84.     }
  85. }

n°713584
xterminhat​e
Si vis pacem, para bellum.
Posté le 01-05-2004 à 16:43:31  profilanswer
 

Si tes operateurs prennent en argument des objets de la classe dans laquelle ils sont définis, je vois pas l'interet de friend.
 

Code :
  1. class Forme
  2. {
  3. public :
  4. virtual bool operator== ( const Forme & ) = 0;
  5. };
  6. class Cercle : public Forme
  7. {
  8. public :
  9. virtual bool operator== ( const Forme & );
  10. };
  11. class Carre : public Forme
  12. {
  13. public :
  14. virtual bool operator== ( const Forme & );
  15. };


Message édité par xterminhate le 01-05-2004 à 17:15:24

---------------
Cordialement, Xterm-in'Hate...
n°713592
Taz
bisounours-codeur
Posté le 01-05-2004 à 16:48:37  profilanswer
 

xterminate > sauf que toi tu n'a absolument rien compris à rien ... alors avant de conseiller ...

mood
Publicité
Posté le 01-05-2004 à 16:48:37  profilanswer
 

n°713593
xterminhat​e
Si vis pacem, para bellum.
Posté le 01-05-2004 à 16:49:10  profilanswer
 

Quel est le problème, j'essais de comprendre en effet ?


---------------
Cordialement, Xterm-in'Hate...
n°713595
Taz
bisounours-codeur
Posté le 01-05-2004 à 16:50:24  profilanswer
 

--Message édité par xterminhate le 01-05-2004 à 16:48:45--

n°713597
Taz
bisounours-codeur
Posté le 01-05-2004 à 16:51:35  profilanswer
 

toute façon essaie avec ta méthode, ça ne peut pas marcher ...

n°713603
xterminhat​e
Si vis pacem, para bellum.
Posté le 01-05-2004 à 16:57:47  profilanswer
 

Forme *c3 = new Cercle(c1);  
Forme *c4 = new Cercle(c2);  
(*c3) == (*c4);
 
C'est bien le == de Forme qui est appelé... et apres ? C'est quoi l'objectif ?


---------------
Cordialement, Xterm-in'Hate...
n°713605
Slayne
Yaouchhh
Posté le 01-05-2004 à 17:03:07  profilanswer
 

xtermin : Mes operateurs prennent des objets de ma classe c'est vrai, mais ils n'influent absolument pas sur elle. Ce ne sont pas des méthodes de classes, et en général je les mets justement à l'extérieur de mon fichier maclasse.cpp.
 
Taz : Ta solution peut etre pas mal en effet. Enfin du moins le résultat c'est ce que je veux. Mais il risque d'y avoir une duplication de code dans mon cas, vu que ce serait plutot à la classe mère de comparer ses paramètres, et pas à ses classes filles.
Tu vois ce que je veux dire ?  

n°713607
Slayne
Yaouchhh
Posté le 01-05-2004 à 17:03:49  profilanswer
 

xterminhate a écrit :

Forme *c3 = new Cercle(c1);  
Forme *c4 = new Cercle(c2);  
(*c3) == (*c4);
 
C'est bien le == de Forme qui est appelé... et apres ? C'est quoi l'objectif ?


 
Mon objectif, c'est que ce soit le == de Cercle qui soit appelé dans ce cas précis.

n°713613
Taz
bisounours-codeur
Posté le 01-05-2004 à 17:14:51  profilanswer
 

Slayne a écrit :


Taz : Ta solution peut etre pas mal en effet. Enfin du moins le résultat c'est ce que je veux. Mais il risque d'y avoir une duplication de code dans mon cas, vu que ce serait plutot à la classe mère de comparer ses paramètres, et pas à ses classes filles.
Tu vois ce que je veux dire ?

non. ça veut rien dire ce que tu dis : si tu as une hiérarchie, chaque classe doit être capable de faire une comparaison entre 2 de ses instances. on a jamais vu quelqu'un rajouter du code à dans sa classe mère à chaque fois qu'on ajouter une classe fille.
 
(qui corresponds à mon bool less(const Class& ) const pour Bar et Foo). on map ces less sur des bool operator<(const Classe&, const Classe& ). là quand on manipule 2 instances de même type (statiquement) on a le comportement classique sans surcout.
 
après on a pas de multimethodes, alors on se débrouille pour rajouter quelque chose sans surcout pour le cas normal: chaque classe dérivant de Base doit fournir un bool less(const Base& ) const.
 
y a un peu de duplication mais pas tant que ça, puisqu'on écrit operator<(const Base&, const Base& ) une fois pour toute, la liaison virtuelle assurant l'appel correct et le cast de la seconde opérande

n°713615
xterminhat​e
Si vis pacem, para bellum.
Posté le 01-05-2004 à 17:17:43  profilanswer
 

Ah je commence à comprendre, mais auras tu le cas suivant :
 

Code :
  1. Carre Car;
  2. Cercle Cer;
  3. Forme *F1,*F2;
  4. F1 = Car;
  5. F2 = &Cer;
  6. *F1 == *F2; // comparaison entre deux objets de classes différentes ?


Message édité par xterminhate le 01-05-2004 à 17:20:43

---------------
Cordialement, Xterm-in'Hate...
n°713618
Taz
bisounours-codeur
Posté le 01-05-2004 à 17:25:14  profilanswer
 

qui n'a aucun sens. essaie mon programme. quand on compare un Foo et un Bar dynamiquement, une exception est lancée

n°713619
Slayne
Yaouchhh
Posté le 01-05-2004 à 17:27:08  profilanswer
 

Forme est abstraite, tu ne peux pas l'instancier xterm, juste utiliser des pointeurs vers des Formes.
En revanche oui je veux pouvoir comparer 2 formes différentes ... ce qui me retournera false.
 
Taz : Tu n'as pas du comprendre ce dont je parlais. Je ne veux pas toucher à la classe mère, je veux juste que la classe mère teste ces propres champs.
 
Par exemple, voila la meilleur solution que j'ai trouvé pour l'instant :  

Code :
  1. class Forme
  2. {
  3. private :
  4. Point centre;
  5. protected :
  6. virtual bool operator==(const Forme &f){
  7.   return this->centre == f.centre;
  8. }
  9. }
  10. class Cercle
  11. : public Forme
  12. {
  13. private :
  14. double rayon;
  15. public :
  16. bool operator==(const Forme &f){
  17.   if (typeid(*this) == typeid(f))
  18.   {
  19.     return this->Forme::operator==(f) && this->rayon == f.rayon;
  20.   }
  21. return false;
  22. }
  23. }


 
Ca ferait ce que je veux, sans duplication, mais ca a le defaut de transformer mon operator== en methode de classe.
Si tu trouves que c'est moche, dis le moi  :D


Message édité par Slayne le 01-05-2004 à 17:29:46
n°713620
Taz
bisounours-codeur
Posté le 01-05-2004 à 17:31:46  profilanswer
 

cai toi qui a rien compris : ton code est complètement pourri d'une part (ne jamais utilisé typeid quand on ne sait pas ce que c'est)
 
après t'as rien compris : rien ne t'empêche de rendre non-virtuelle ma Base::less et de faire en sorte que chaque Classe::less(const Class& ) const fasse appel à Base::less(const Base & ) const

n°713621
Taz
bisounours-codeur
Posté le 01-05-2004 à 17:33:09  profilanswer
 

toute façon tout ça est un peu tendancieux, confier aux opérateur a X b de faire les conversions ... je pense qu'il vaut mieux essayer d'éviter et de s'assurer soit même par cast de ce que sont les objets avec de leur appliquer des opérations typées et symétriques

n°713623
xterminhat​e
Si vis pacem, para bellum.
Posté le 01-05-2004 à 17:37:31  profilanswer
 

Ce n'est pas compliqué : il ne faut pas avoir à comparer deux objets de type différents ! C'etait l'une de mes premières remarques au sujet de la conception de ton programme....


Message édité par xterminhate le 01-05-2004 à 17:37:49

---------------
Cordialement, Xterm-in'Hate...
n°713624
xterminhat​e
Si vis pacem, para bellum.
Posté le 01-05-2004 à 17:38:51  profilanswer
 

Ou alors, il faut que == soit défini dans Forme et compare des attributs qui sont communs à toutes les formes hérités (genre : surface, nb de sommets, ...etc).


Message édité par xterminhate le 01-05-2004 à 17:39:25

---------------
Cordialement, Xterm-in'Hate...
n°713625
Slayne
Yaouchhh
Posté le 01-05-2004 à 17:44:36  profilanswer
 

Taz a écrit :

cai toi qui a rien compris : ton code est complètement pourri d'une part (ne jamais utilisé typeid quand on ne sait pas ce que c'est)
Supair  [:meganne]  
 
après t'as rien compris : rien ne t'empêche de rendre non-virtuelle ma Base::less et de faire en sorte que chaque Classe::less(const Class& ) const fasse appel à Base::less(const Base & ) const
Ca revient a faire ce que j'ai fait quoi sauf pour Base


 
Et le castage est impossible si je veux créer une liste de Forme par exemple. Quand je voudrais en supprimer une, il faudra bien que je compare 2 formes différentes entre elles  :o  
Merci quand meme de ta participation mais si c'est pour dire des conneries ou insulter tu peux laisser ta place merci  :hello:

n°713626
Slayne
Yaouchhh
Posté le 01-05-2004 à 17:45:09  profilanswer
 

xterminhate a écrit :

Ou alors, il faut que == soit défini dans Forme et compare des attributs qui sont communs à toutes les formes hérités (genre : surface, nb de sommets, ...etc).


 
C'est ça  :)

n°713627
xterminhat​e
Si vis pacem, para bellum.
Posté le 01-05-2004 à 17:46:34  profilanswer
 

Ben alors tu n'as pas besoin de tout ce qui s'est écrit ici bas. Tu fais juste == non virtual, non friend, dans Forme et terminé.


---------------
Cordialement, Xterm-in'Hate...
n°713628
xterminhat​e
Si vis pacem, para bellum.
Posté le 01-05-2004 à 17:49:58  profilanswer
 

Déclares les attributs communs dans Forme et mets les à jour depuis des classes dérivées....


Message édité par xterminhate le 01-05-2004 à 17:50:12

---------------
Cordialement, Xterm-in'Hate...
n°713630
Slayne
Yaouchhh
Posté le 01-05-2004 à 17:51:31  profilanswer
 

xterminhate a écrit :

Ben alors tu n'as pas besoin de tout ce qui s'est écrit ici bas. Tu fais juste == non virtual, non friend, dans Forme et terminé.


 
Ca marchera pour comparer les attributs communs aux 2 formes c'est vrai, mais pas pour comparer les spécifités de chaque forme.
Le == de forme teste si le centre de chaque forme est le meme, le == de cercle appelera celui de forme et testera ces propres attributs (son rayon).

n°713631
xterminhat​e
Si vis pacem, para bellum.
Posté le 01-05-2004 à 17:54:45  profilanswer
 

Un truc comme ca, te conviendrait il ?
 
1) comparer les attributs communs des deux objets
2) comparer le type des deux objets
3') si les types sont identiques alors comparer les attributs spécifiques.
3" ) si les types sont différents, ... rien.


---------------
Cordialement, Xterm-in'Hate...
n°713633
xterminhat​e
Si vis pacem, para bellum.
Posté le 01-05-2004 à 17:56:24  profilanswer
 

Pour comparer le type de deux objets c'est pas compliqué en le faisant soit même.
 
Tu déclares un fonctions : virtual std::string type() = 0; dans Forme et par exemple : virtual std::string type() { reutrn "Cercle"; } dans la classe cercle, etc...


---------------
Cordialement, Xterm-in'Hate...
n°713635
xterminhat​e
Si vis pacem, para bellum.
Posté le 01-05-2004 à 17:57:07  profilanswer
 

et tu fais un truc tout bete : objet1.type() == objet2.type()...


---------------
Cordialement, Xterm-in'Hate...
n°713636
Taz
bisounours-codeur
Posté le 01-05-2004 à 17:59:37  profilanswer
 

non. à partir du moment ou les types diffèrent, il faut lancer une erreur. donc  
 
si même type
  - comparer
sinon
  - lancer exception
 
 
je comprends pas vos histoires, si Cercle décide que operator==(Cercle, Cercle) reposent sur operator==(Forme, Forme) il doit pouvour le faire, et si carré décide que son operator)== n'a besoin de rien d'autre, il faut le laisser faire aussi

n°713637
Taz
bisounours-codeur
Posté le 01-05-2004 à 17:59:55  profilanswer
 

xterminhate a écrit :

et tu fais un truc tout bete : objet1.type() == objet2.type()...

jamais
 
edit: non mais tu le fais exprès ou t'as vraiment rien compris à rien ?


Message édité par Taz le 01-05-2004 à 18:00:24
n°713638
xterminhat​e
Si vis pacem, para bellum.
Posté le 01-05-2004 à 18:01:33  profilanswer
 

qu'est ce que ca gène ?


---------------
Cordialement, Xterm-in'Hate...
n°713640
Taz
bisounours-codeur
Posté le 01-05-2004 à 18:03:19  profilanswer
 

que tu ne t'y connais absolument pas, que tu conseilles tout et n'importe quoi, tu ferais mieux d'apprendre un peu avant d'être de mauvais conseil

n°713641
xterminhat​e
Si vis pacem, para bellum.
Posté le 01-05-2004 à 18:04:01  profilanswer
 

C'est facile de dire ca :) Je m'enerve pas au moins !


---------------
Cordialement, Xterm-in'Hate...
n°713643
Taz
bisounours-codeur
Posté le 01-05-2004 à 18:05:33  profilanswer
 

ben c'est pas sympa de conseiller des choses entre débutants quand on y connait rien ...

n°713644
xterminhat​e
Si vis pacem, para bellum.
Posté le 01-05-2004 à 18:06:33  profilanswer
 

Pas de problèmes :)


---------------
Cordialement, Xterm-in'Hate...
n°713647
xterminhat​e
Si vis pacem, para bellum.
Posté le 01-05-2004 à 18:08:57  profilanswer
 


 
Pourquoi pas ?


---------------
Cordialement, Xterm-in'Hate...
mood
Publicité
Posté le   profilanswer
 

 Page :   1  2
Page Précédente

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

  Ou placer un virtual operator== ?

 

Sujets relatifs
Placer image dans le coin[CSS] placer une image en haut a droite d'un cadre avec IE...
[C] Placer un délai dans l'éxecution d'un programmeplacer une boite de dialogue
visual c++ placer des controles sur une formproblème avec 'operator type();' : ambiguité
Overlord operator <<, aide svpSurcharge d operateur = et virtual , ca va ensemble ?
manière la plus rapide de placer un bit[PHP-objet] Dans quelle classe placer cette methode ?
Plus de sujets relatifs à : Ou placer un virtual operator== ?


Copyright © 1997-2025 Groupe LDLC (Signaler un contenu illicite / Données personnelles)