Ou placer un virtual operator== ? - C++ - Programmation
Marsh Posté le 01-05-2004 à 16:08:45
Fait voir ta classe de base qui contient un opérateur... C'est pas clair ton histoire.
Tu peux ecrire ca...
Code :
|
Marsh Posté le 01-05-2004 à 16:20:13
Pour reprendre ton exemple, le probleme c'est que je définis toujours mes operateurs externes comme ca :
Code :
|
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 )
Mais bon effectivement je peux tout réécrire comme ça, mais est ce vraiment une bonne solution ? (c'est peut etre la seule ..)
Marsh Posté le 01-05-2004 à 16:20:38
je pense pas que ça soit très sain de faire des opérateurs virtuels, encore moins les binaires
Marsh Posté le 01-05-2004 à 16:22:43
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 ?
Marsh Posté le 01-05-2004 à 16:34:22
Bon d'accord je prend un exemple qui j'espere sera plus clair.
Comme classe mère, je prend une classe abstraite Forme.
Code :
|
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 :
|
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
Marsh Posté le 01-05-2004 à 16:39:03
Code :
|
Marsh Posté le 01-05-2004 à 16:43:31
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 :
|
Marsh Posté le 01-05-2004 à 16:48:37
xterminate > sauf que toi tu n'a absolument rien compris à rien ... alors avant de conseiller ...
Marsh Posté le 01-05-2004 à 16:49:10
Quel est le problème, j'essais de comprendre en effet ?
Marsh Posté le 01-05-2004 à 16:50:24
--Message édité par xterminhate le 01-05-2004 à 16:48:45--
Marsh Posté le 01-05-2004 à 16:51:35
toute façon essaie avec ta méthode, ça ne peut pas marcher ...
Marsh Posté le 01-05-2004 à 16:57:47
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 ?
Marsh Posté le 01-05-2004 à 17:03:07
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 ?
Marsh Posté le 01-05-2004 à 17:03:49
xterminhate a écrit : Forme *c3 = new Cercle(c1); |
Mon objectif, c'est que ce soit le == de Cercle qui soit appelé dans ce cas précis.
Marsh Posté le 01-05-2004 à 17:14:51
Slayne a écrit : |
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
Marsh Posté le 01-05-2004 à 17:17:43
Ah je commence à comprendre, mais auras tu le cas suivant :
Code :
|
Marsh Posté le 01-05-2004 à 17:25:14
qui n'a aucun sens. essaie mon programme. quand on compare un Foo et un Bar dynamiquement, une exception est lancée
Marsh Posté le 01-05-2004 à 17:27:08
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 :
|
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
Marsh Posté le 01-05-2004 à 17:31:46
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
Marsh Posté le 01-05-2004 à 17:33:09
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
Marsh Posté le 01-05-2004 à 17:37:31
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....
Marsh Posté le 01-05-2004 à 17:38:51
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).
Marsh Posté le 01-05-2004 à 17:44:36
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) |
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
Merci quand meme de ta participation mais si c'est pour dire des conneries ou insulter tu peux laisser ta place merci
Marsh Posté le 01-05-2004 à 17:45:09
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
Marsh Posté le 01-05-2004 à 17:46:34
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é.
Marsh Posté le 01-05-2004 à 17:49:58
Déclares les attributs communs dans Forme et mets les à jour depuis des classes dérivées....
Marsh Posté le 01-05-2004 à 17:51:31
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).
Marsh Posté le 01-05-2004 à 17:54:45
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.
Marsh Posté le 01-05-2004 à 17:56:24
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...
Marsh Posté le 01-05-2004 à 17:57:07
et tu fais un truc tout bete : objet1.type() == objet2.type()...
Marsh Posté le 01-05-2004 à 17:59:37
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
Marsh Posté le 01-05-2004 à 17:59:55
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 ?
Marsh Posté le 01-05-2004 à 18:01:33
qu'est ce que ca gène ?
Marsh Posté le 01-05-2004 à 18:03:19
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
Marsh Posté le 01-05-2004 à 18:04:01
C'est facile de dire ca Je m'enerve pas au moins !
Marsh Posté le 01-05-2004 à 18:05:33
ben c'est pas sympa de conseiller des choses entre débutants quand on y connait rien ...
Marsh Posté le 01-05-2004 à 18:06:33
Pas de problèmes
Marsh Posté le 01-05-2004 à 18:08:57
Reply
Marsh Posté le 01-05-2004 à 16:04:31
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