Heritage Fonction abstraite, Probleme conteneur Heterogene

Heritage Fonction abstraite, Probleme conteneur Heterogene - C++ - Programmation

Marsh Posté le 22-05-2006 à 16:24:26    

Bonjour a tous,
 
j ai un petit souci d acces avec l heritage et les interfaces. Je dispose de 2 classes abstraites, l une heritant de l autre :  

Code :
  1. class IObject
  2. {
  3.   public  :
  4.     virtual string    ToString() const = 0;           
  5.     virtual string    GetType() const = 0;
  6. }
  7. class IOperand : public IObject
  8. {
  9.   public:
  10.     virtual IObject*  Add(const IOperand &object) = 0;         
  11.     virtual IObject*  Subtract(const IOperand &object) = 0;   
  12. }


Voila donc ce sont 2 classes abstraites. Je doit donc , pour ouvoir implementer ces interfaces, les faire heriter.
Donc je pense proceder ainsi :  

Code :
  1. class myclass : public IOperand
  2. {
  3. // bla bla
  4. }


Donc je dois definir le code de toutes les fonctions des interfaces puisque ce sont des methodes pures. Je vais creer plusieurs classes differentes qui heriteront de IOperand.
Mon souci reside dans le stockage heterogene de ces classes. Je dois creer un conteneur de type IObject ( puisque les fonctions renvoie des IObject) mais comment faire pour appeler les methodes add et substract si je suis avec un type IObject. Je ne peux pas caster le IObject en IOperand !!!!! .
 
Avez vous une solution ou une piste pour mes recherches.
Merci d avance pour vos reponses.  :hello:


Message édité par loupin le 22-05-2006 à 16:32:56
Reply

Marsh Posté le 22-05-2006 à 16:24:26   

Reply

Marsh Posté le 22-05-2006 à 18:10:14    

heu dynamic_cast<> si tu veux rester avec une collection de IObject*, et pouvoir savoir si tu passer par un IOperand* (dynamic_cast<> te retournes un 0 si le cast est pas possible)
 
mais c'est pas plus simple d'avoir une collection de IOperand * ?
(oublie pas le destructeur virtuel)

Reply

Marsh Posté le 22-05-2006 à 18:48:26    

Comme bjone, ici tu as défini que tu effectuais des opérations sur des IOperand, pas sur des IObject.
 
Et le fait que tes fonctions renvoient du IObject ne me semble pas logique, elles devraient renvoyer du IOperand pour être cohérentes avec l'environnement (les opérations sont appliquées sur des IOperand et prennent en arguments des IOperand, pourquoi donc renverraient-elles des IObject?)
 
Et accessoirement, pourquoi renvoies tu des IObject* alors que tu prends des IOperand&? Là encore tu as une dichotomie entre tes interfaces de sortie :/
 
Soit tu utilises des pointeurs partout soit tu utilises des références partout, mais à mixer les deux tu vas te vautrer à un moment où à un autre.


---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 22-05-2006 à 19:05:28    

ou là wais j'avais pas vu le Add(const IOperand &object), c'est pet-gueule ça: il vaux mieux du Add(const IOperand  *) quand tu manipules des objets virtuels.

Reply

Marsh Posté le 22-05-2006 à 19:14:17    

bjone a écrit :

ou là wais j'avais pas vu le Add(const IOperand &object), c'est pet-gueule ça: il vaux mieux du Add(const IOperand  *) quand tu manipules des objets virtuels.


? Pourquoi c'est pète gueule ?

Reply

Marsh Posté le 22-05-2006 à 19:19:33    

ben oui, reference ou adresse c'est ok pour le polymorphisme

Reply

Marsh Posté le 22-05-2006 à 19:27:54    

masklinn a écrit :

Soit tu utilises des pointeurs partout soit tu utilises des références partout, mais à mixer les deux tu vas te vautrer à un moment où à un autre.


Je ne vois pas vraiment le risque, le compilateur nous épargne ces problèmes normalement. Le risque, c'est l'utilisation des pointeurs. De mon point de vue, et dans la mesure du possible, c'est jamais de pointeur en paramètre de fonction. Pour le type de retour, on pourra préférer un retour par valeur, ou éventuellement un retour par référence constante si on a pas à modifier l'objet.
Mais des fois, on veut pouvoir s'en servir de manière polymorphique, vouloir stocker le retour dans un conteneur, etc. Et la, le retour d'un pointeur peut-etre approprié. C'est plus casse gueule, car il faut savoir qui libère sa mémoire.

Reply

Marsh Posté le 22-05-2006 à 19:29:50    

++fab a écrit :

Je ne vois pas vraiment le risque, le compilateur nous épargne ces problèmes normalement.


Je ne parlais pas d'un point de vue de risque mais d'un point de vue de cohérence des interfaces, entrer en références et sortir en pointeurs c'est pas cohérent, et si on veut chainer des opérations on va se retrouver avec un grand n'importe quoi [:spamafote]


---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 22-05-2006 à 19:32:45    

et comment tu veux faire autrement ?? tu vas pas transformer tes paramettres en pointeurs sous pretexte que tu retourne un pointeur ?

Reply

Marsh Posté le 22-05-2006 à 19:37:13    

masklinn a écrit :

Je ne parlais pas d'un point de vue de risque mais d'un point de vue de cohérence des interfaces, entrer en références et sortir en pointeurs c'est pas cohérent, et si on veut chainer des opérations on va se retrouver avec un grand n'importe quoi [:spamafote]


Je t'avoues que je n'ai -- je crois -- jamais de fonction qui mélange les deux, mais je ne vois pas en quoi c'est incohérent. Et je crois qu'on peut imaginer des cas ou cela aurait un sens.  
 
Et dès qu'il y a des pointeurs, ça devient complexe de chainer les opérations de toute manière.

Reply

Marsh Posté le 22-05-2006 à 19:37:13   

Reply

Marsh Posté le 22-05-2006 à 19:42:19    

skelter a écrit :

et comment tu veux faire autrement ?? tu vas pas transformer tes paramettres en pointeurs sous pretexte que tu retourne un pointeur ?


Bien sûr que si, soit tout ce qui est à l'extérieur est sous forme de pointeurs soit tout est sous forme de références [:pingouino]
 
(je parle du cas pointeurs/références hein si les arguments sont passés par valeur tu vas pas les changer en pointeurs naturellement)

++fab a écrit :

Je t'avoues que je n'ai -- je crois -- jamais de fonction qui mélange les deux


Ben non, les références et les pointeurs sont déjà assez chiant par eux mêmes pour pas en faire de mélanges

++fab a écrit :

mais je ne vois pas en quoi c'est incohérent.


Ca force à mixer pointeurs et références à la fois dans le code de la fonction et dans le code appelant la fonction, c'est une très bonne manière de se mélanger les pinceaux et de se vautrer.
 
Pointeurs et références ayant fondamentalement le même rôle, mélanger les deux est source d'erreur sans avoir aucun avantage [:spamafote]  

++fab a écrit :

Et je crois qu'on peut imaginer des cas ou cela aurait un sens.


Peut-être, mais celui décrit dans ce sujet n'en est pas un [:spamafote]  


---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 22-05-2006 à 19:48:32    

je vois pas ou est le probleme dans cet exemple, si il ne peut renvoyer autre chose qu'un pointeur je vois pas pour quoi il faudrais prendre un 'const IOperand *' en parametre

Reply

Marsh Posté le 22-05-2006 à 19:52:22    

d'ailleur 'const &' c'est absolument transparent dans le code appelant, ca pourait etre une valeur que ca ne changerais ni la syntaxe ni la sémantique

Reply

Marsh Posté le 22-05-2006 à 19:54:55    

skelter a écrit :

ben oui, reference ou adresse c'est ok pour le polymorphisme


 
il me semblait qu'il y avait des cas particuliers vis à vis du passage par référence, je dois me planter :/
 
disons que le premier truc de discutable c'est de retourner un IObject * au lieu d'un IOperand * pour Add/Substract, si c'est l'objet courant ou celui passé en paramètre...

Reply

Marsh Posté le 22-05-2006 à 19:55:42    

skelter a écrit :

je vois pas ou est le probleme dans cet exemple, si il ne peut renvoyer autre chose qu'un pointeur je vois pas pour quoi il faudrais prendre un 'const IOperand *' en parametre


Chais pas, on appelle ça de la logique de base, j'envoie du Foo je récupère du Foo, j'envoie du Foo* je récupère du Foo*, envoyer du Foo et recevoir du Foo* est complètement arbitraire et illogique [:spamafote]  

skelter a écrit :

d'ailleur 'const &' c'est absolument transparent dans le code appelant, ca pourait etre une valeur que ca ne changerais ni la syntaxe ni la sémantique


Ah ouais et le retour d'un IOPerand * c'est vachement transparenty pour le code appelant [:pingouino]


---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 22-05-2006 à 20:15:43    

Citation :

Bien sûr que si, soit tout ce qui est à l'extérieur est sous forme de pointeurs soit tout est sous forme de références [:pingouino]


 
Absolument pas d'accord. Les paramètres et le type de retour sont à dissocier complètement (Je considère qu'il n'y a pas de paramètres inout/out) Pour les paramètres, si tu veux t'assurer que tu peux passer une rvalue (via const& ), et que tu veux être en sécurité du point de vue de la mémoire, les références sont la seule alternative, et éclipse celle des pointeurs.
 
Pour le cas du type de retour, ce qui te conditionne, ce sont les propriétés et l'usage que tu fais de l'objet que tu retournes. Est-il copie constructible, assignable, va-t'on le mofifier et ne lui appliquer que des fonctions membres const, va-t'on le stocker dans un container qui requiert la propriété assignable, default-constructible, comment va-t'on gérer sa durée de vie ?
 
Ces deux choix ne peuvent pas être liés.
 
 

Citation :

Ben non, les références et les pointeurs sont déjà assez chiant par eux mêmes pour pas en faire de mélanges


Note que ce n'était pas un objectif, juste une observation.
 
 

Citation :

Pointeurs et références ayant fondamentalement le même rôle, mélanger les deux est source d'erreur sans avoir aucun avantage [:spamafote]


Non, voir ci dessus.  
 

Citation :

Peut-être, mais celui décrit dans ce sujet n'en est pas un [:spamafote]


Possible, je me suis écarté du sujet du PO.  
 
(reply buggé)

Reply

Marsh Posté le 22-05-2006 à 20:27:40    

masklinn a écrit :

Chais pas, on appelle ça de la logique de base, j'envoie du Foo je récupère du Foo, j'envoie du Foo* je récupère du Foo*, envoyer du Foo et recevoir du Foo* est complètement arbitraire et illogique [:spamafote]


 
Si tu envoies du Foo et que tu reçois du Bar*, est-ce illogique (dans ta logique  :whistle: ) ?
 

masklinn a écrit :

Ah ouais et le retour d'un IOPerand * c'est vachement transparenty pour le code appelant [:pingouino]


Quel rapport avec la transparance de const& ?

Message cité 1 fois
Message édité par ++fab le 22-05-2006 à 20:29:33
Reply

Marsh Posté le 22-05-2006 à 20:29:28    

++fab a écrit :

Si je envoies du Foo et que tu renvoies du Bar*, est-ce illogique (dans ta logique  :whistle: ) ?


Non.


---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 22-05-2006 à 20:29:58    

j'ai édité :|

Reply

Marsh Posté le 22-05-2006 à 21:33:57    

alors c'est que tu considères qu'il est logique qu'une fonction qui "relaye" son paramètre, le relaye avec le même type. Mais je crois que ma réponse plus détaillé ci-cessus s'applique aussi dans ce cas.

Reply

Marsh Posté le 22-05-2006 à 22:36:35    

moi je demande des exemples, des citations, des references
regarde les bibliotheques de pointe en c++ et tu verras qu'au niveau des interface cette regle n'est (forcement) pas toujours respectée, d'ailleur ce n'est pas une regle en soit, elle ne peut pas contitionnée le type des parametres et du retour comme l'a dit ++fab
en fait c'est des cracks tout ca !

Reply

Marsh Posté le 22-05-2006 à 23:22:43    

alor, je suis tout a fait d accord que cé pa très logique de prendre un IOperand et de renvoyer un IObject mais le sujet est fait comme ca, je pense que c est fait expres.  
 
Ensuite, je vais tester demain pour le dynamic mais je pense que ca va correspondre a ce que je voulais, cé un peu de la bidouille mais cé ce que je cherchais .
 
Je tiens a remercier tous ceux qui ont repondus a ce post.
 
Je passe le sujet en resolu demain si ca fonctionne.

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed