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

  FORUM HardWare.fr
  Programmation
  C++

  Comment vérifier si un objet implémente une interface?

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Comment vérifier si un objet implémente une interface?

n°2105492
kray
Bad show?
Posté le 09-10-2011 à 23:30:08  profilanswer
 

Bonjour,
 
Je regarde de la doc sur le net et sur des bouquins, mais je n'arrive pas à trouver de méthode complète et saine pour gérer les interfaces en C++ (sans faire du COM).  
 
Mon problème est que j'ai plusieurs objets hétéroclites, certains ayant une "interface" A(ils héritent de A, A ayant des fonctions virtuelles et d'autres pas, un des mécanismes que je retrouve le plus dans les doc sur les interfaces) , d'autres non. Je stocke dans un tableau de void* des pointeurs sur ces objets.(car ils subissent un traitement commun). Néanmoins, j'aimerai être capable dans ce traitement d'utiliser des méthodes de l'interface A si l'objet la possède.
 
Or le castage "comme en C" ne me permet pas de savoir si ce que je récupère implémente l'interface, et le dynamic_cast n'accepte pas les void*

Code :
  1. Class A { std::string getName(); };
  2. Class B: public A {};
  3. Class C{};
  4. void* element;
  5. ...
  6. A* itf = (A*) element;
  7. itf->getName(); //OK si element est en fait un objet B, Run Time error si c'est C


 
Est-ce qu'on peut implémenter à moindre frais un genre de QueryInterface, ou est-ce que je vais être obligé de faire hériter toutes mes classes type B et C d'une classe "bidon" qui ne sert à rien sauf à ne pas utiliser de void *(et je ne sais pas si c'est plus propre)? Ou il y a t-il une autre solution pour vérifier si l'objet a bien l'interface(et je conserve donc mes void*)
 
 
Merci


---------------
I guess my real ennemy is me
mood
Publicité
Posté le 09-10-2011 à 23:30:08  profilanswer
 

n°2105495
Joel F
Real men use unique_ptr
Posté le 10-10-2011 à 06:53:18  profilanswer
 

http://www.boost.org/doc/libs/1_47 [...] se_of.html

 

boost::is_base_of<A,B>::value renvoit true si B herite de A

 


Ensuite, ton void* est une merde infame. Utilise le polymorphisme proprement en redant getName() virtuelle

 
Code :
  1. class A { virtual std::string getName(); };
  2. class B: public A {};
  3. class C{};
  4. A* element = new B;
  5. element->getrName();

`

 


Revoir les bases me parait une bonne idée. On ne C-cast pas des objets et surtout pas a partir d'un void*.

 


Message cité 1 fois
Message édité par Joel F le 10-10-2011 à 06:58:37
n°2105644
kray
Bad show?
Posté le 10-10-2011 à 19:03:58  profilanswer
 

Joel F a écrit :

http://www.boost.org/doc/libs/1_47 [...] se_of.html
 
boost::is_base_of<A,B>::value renvoit true si B herite de A
 
 
Ensuite, ton void* est une merde infame. Utilise le polymorphisme proprement en redant getName() virtuelle
 

Code :
  1. class A { virtual std::string getName(); };
  2. class B: public A {};
  3. class C{};
  4. A* element = new B;
  5. element->getrName();

`
 
 
Revoir les bases me parait une bonne idée. On ne C-cast pas des objets et surtout pas a partir d'un void*.
 
 


 
Oui, j'ai tenté le void* en désespoir de cause...
 Mais du coup, puisque je veux stocker des objets différents dans une meme liste, je fais comment? Une classe mère dont toutes mes classent héritent? Genre:

Code :
  1. class Mother {};
  2.     class A : public Mother { virtual std::string getName(); };
  3.     class B: public A {};
  4.     class C: public Mother {};
  5.     std::queue<Mother*> maliste;
  6.      B* b = new B;
  7.      C*c = new C
  8.      maliste.push(b); maliste.push(c);


Mais après, pour savoir si ce qui sort d'une maliste.front() implémente B ou pas, je fais comment? Dynamic_cast? Car le is_base_of ne permet pas de le savoir?
 
Sinon,  j'ai des fonctions virtuelles lorsque l'objet doit les implémenter "différemment" (style des calculs, mais le traitement derrière le getname est commun à tout mes objets ayant l'interface).
Du coup c'est effectivement pas propre du tout car l'interface implémente certaines fonctions...  :sweat:  


---------------
I guess my real ennemy is me
n°2105688
Joel F
Real men use unique_ptr
Posté le 10-10-2011 à 22:42:39  profilanswer
 

ton probleme ets mal poser; si tu mets tes objets dans une liste, il doivent avoir unt ruc en commun sinon c'est n'imp.
 
sinon le pattern Visitor pourra aussi aider

n°2106406
boulgakov
Posté le 14-10-2011 à 14:57:04  profilanswer
 

kray a écrit :

je veux stocker des objets différents dans une meme liste


 
Je dirais qu'a priori c'est bizarre de vouloir faire ça et qu'il y a put-être une erreur de conception en amont. Peux-tu en dire plus sur le contexte ? Comme dit Joël, si tu ranges des objets dans le même conteneur c'est qu'ils se "ressemblent" en quelque chose, sinon pourquoi les mettre ensemble ?
 
 
 

n°2106434
Xavier_OM
Monarchiste régicide (fr quoi)
Posté le 14-10-2011 à 17:34:01  profilanswer
 

Soit une liste de graine, comment séparer le bon grain (qui implémente ton interface) de l'ivraie (qui ne l'implémente pas) ?
 
disclaimer : je suis sans doute rouillé en C++, à prendre avec des pincettes :o
 

Code :
  1. #include <typeinfo>
  2. #include <iostream>
  3. #include <vector>
  4. using namespace std;
  5. class Graine {
  6.     public:
  7.         virtual ~Graine() { }
  8. };
  9. class BonGrain : public Graine {
  10.     public:
  11.         virtual ~BonGrain() { }
  12. };
  13. class Ivraie : public Graine {
  14.     public:
  15.         virtual ~Ivraie() { }
  16. };
  17. void separe(vector<Graine*> &recolte, vector<BonGrain> &grains, vector<Ivraie> &ivraies) {
  18.     for(vector<Graine*>::iterator i(recolte.begin()); i != recolte.end(); ++i) {
  19.         if(BonGrain* bon_grain = dynamic_cast<BonGrain*>(*i)) {
  20.             grains.push_back(*bon_grain);
  21.         }
  22.         else if(Ivraie* ivraie = dynamic_cast<Ivraie*>(*i)) {
  23.             ivraies.push_back(*ivraie);
  24.         }
  25.         else {
  26.             cerr << "Je ne sais pas ce que c'est que cette cochonnerie !\n";
  27.         }
  28.         delete *i;
  29.     }
  30.     recolte.clear();
  31. }
  32. int main() {
  33.     vector<Graine*> recolte;
  34.     vector<BonGrain> grains;
  35.     vector<Ivraie> ivraies;
  36.     recolte.push_back(new BonGrain);
  37.     recolte.push_back(new Ivraie);
  38.     recolte.push_back(new BonGrain);
  39.     separe(recolte, grains, ivraies);
  40.     cout << grains.size() << " bon grains et " << ivraies.size() << " ivraies\n";
  41.     return 0;
  42. }



---------------
Il y a autant d'atomes d'oxygène dans une molécule d'eau que d'étoiles dans le système solaire.
n°2106470
Joel F
Real men use unique_ptr
Posté le 14-10-2011 à 19:50:04  profilanswer
 

if avec dynamic_cast == Visitor qui ne demande qu'a etre implementer :o

n°2106472
Xavier_OM
Monarchiste régicide (fr quoi)
Posté le 14-10-2011 à 20:10:53  profilanswer
 

Joel F a écrit :

if avec dynamic_cast == Visitor qui ne demande qu'a etre implementer :o


 
Yep j'avoue :o (j'espère qu'il cherche bien un truc comme ça et pas une approche plus "réflexivité" )


---------------
Il y a autant d'atomes d'oxygène dans une molécule d'eau que d'étoiles dans le système solaire.
n°2107720
kray
Bad show?
Posté le 23-10-2011 à 17:28:19  profilanswer
 

En fait, j avais un problème de conception, et je peux effectivement utiliser la méthode de l exemple bon grain / ivraie (ou le pattern visitor )  : tout mes objets peuvent dériver d un objet unique. Par contre je souhaiterai quand meme implémenter des interfaces via queryinterface comme sous windows. Par exemple, un objet voiture ou moto dérive bien d un objet véhicule. Donc la dessus, pb résolu. Mais j aimerai bien une interface human_controlled, ou ia_controlled ou statique par exemple. Et être capable de les utiliser via queryinterface. Je sais que c est possible, j eu utilisé du queryinterface il y à quelques années, mais je sais pas comment c'était implementé derrière.


Message édité par kray le 23-10-2011 à 17:30:07

---------------
I guess my real ennemy is me
n°2111042
Lightness1​024
Posté le 11-11-2011 à 23:54:12  profilanswer
 

oui mais reflechi, une voiture EST un vehicule, par contre human_controlled n'est pas un objet. donc ca va pas, ca ne peux pas etre un parent.
par contre tu peux faire heriter vehicule de "controllable" et ensuite mettre des états dans controllable: genre contenir un "controller" qui pourrait par exemple avoir deux types de classes enfant "ia" et "human".
tu vois ?
attention a ne pas heriter là ou ca n'a pas de sens, toujours voir l'heritage comme le verbe "EST".
aussi, si y'a bien un truc que j'ai appris, copier microsoft n'est pas une bonne idée. je voulais le faire aussi quand j'etais jeune mais c'etait parce que j'avais un manque de perspective. normal quand la msdn nous apprend tout au lieu d'un vrai prof d'info...


---------------
http://projets.6mablog.com/
mood
Publicité
Posté le 11-11-2011 à 23:54:12  profilanswer
 

n°2111068
Joel F
Real men use unique_ptr
Posté le 12-11-2011 à 09:13:10  profilanswer
 

"EST" c'est l'heritage public, pour l'heritage privé c'ets plutot "ETAIT".


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

  Comment vérifier si un objet implémente une interface?

 

Sujets relatifs
[Javascript] Override objet topexercice programmation orienté objet c++
VBS: verifier existance OU dans l'ADInterface Graphique et gestion de fichiers
Recherche un développeur PHP Objet[VBA] Type utilisateur et objet
php5 objet performance ?Recherche d'objet avec des coordonées.
VBA: La méthode de l'objet Worksheet a echoué 
Plus de sujets relatifs à : Comment vérifier si un objet implémente une interface?


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