Héritage et plugin

Héritage et plugin - C++ - Programmation

Marsh Posté le 14-03-2006 à 09:55:05    

Salut !
 
Mon projet consiste en une série d'héritage de classes : la classe C hérite de la classe B, qui elle-même hérite de la classe A (C ->
B -> A).
À chaque fois que l'on descend dans l'héritage, j'ajoute des méthodes plus spécifiques.
Dans mon projet, je dois facilement ajouter de nouvelles fonctions, je me suis donc tourné vers l'utilisation de plugins (dlopen, etc...).
Dans mon cas, les plugins sont donc des implémentations des classes B et C.
Mon problème survient lors de l'instanciation des plugins : puisque seule la classe A est connue de mon système de plugin, les nouvelles méthodes implémentées dans les classes B et C ne sont pas instanciables.
Existe-t-il une solution à ce problème ?
Ou bien dois-je obligatoirement utiliser les mêmes méthodes, mais pas forcément implémentées de la même manière ?
 
Merci d'avance.

Reply

Marsh Posté le 14-03-2006 à 09:55:05   

Reply

Marsh Posté le 15-03-2006 à 15:21:11    

je vois pas comment tu fais pour utiliser directement B::foo quand t'as un A*/A& ... donc je ne vois pas le problème.

Reply

Marsh Posté le 16-03-2006 à 09:48:52    

Hu !
 

Code :
  1. A.hpp :
  2. -------
  3. class A
  4. {
  5. T _huhu
  6. public:
  7. A(T huhu) : _huhu(huhu) {};
  8. virtual ~A() {};
  9. virtual void compute() = 0;
  10. };
  11. typedef A* createPluginA();


 

Code :
  1. B.hpp :
  2. -------
  3. class B : public A
  4. {
  5. protected:
  6. T2 _haha
  7. public:
  8. B(T huhu, T2 haha) : A(huhu), _haha(haha) {};
  9. virtual ~B() {};
  10. virtual void compute();
  11. virtual void pouet();
  12. };
  13. B.cpp :
  14. -------
  15. void B::compute()
  16. {
  17. cout << "compute" << endl;
  18. }
  19. void B::pouet()
  20. {
  21. cout << "pouet" << endl;
  22. }
  23. extern "C"
  24. {
  25. A* createA(T huhu, T2 haha)
  26. {
  27.   return new B(huhu, haha);
  28. }
  29. }


 

Code :
  1. main.cpp :
  2. ----------
  3. #include "A.hpp"
  4. A* loadPluginA(T huhu, T2 haha)
  5. {
  6. void* handle = dlopen("libB.so", RTLD_NOW | RTLD_GLOBAL);
  7. if(handle){
  8.   createPluginA* create = (createPluginA*) dlsym(handle, "createA" ); 
  9.   if(create)
  10.   {     
  11.    return create(huhu, haha); 
  12.   }
  13.   dlclose(handle);
  14. }
  15. }
  16. int main(int argc, char* argv[])
  17. {
  18. A* b = loadPluginA(huhu, haha);
  19. b->pouet(); //marche pas ^^, et c'est normal! Mais comment faire ?
  20. return 0;
  21. }


Message édité par Riot le 16-03-2006 à 09:49:32
Reply

Marsh Posté le 16-03-2006 à 10:05:24    

Citation :

A* b = loadPluginA(huhu, haha);
b->pouet(); //marche pas ^^, et c'est normal! Mais comment faire ?


 
Bah définir pouet() en méthode virtuelle dans A [:spamafote]


Message édité par smaragdus le 16-03-2006 à 10:05:39
Reply

Marsh Posté le 16-03-2006 à 11:07:52    

Nan j'veux pas ! :o
Dans mon précédent post, j'ai simplifié les choses en ne mettant que 2 classes, normalement il peut encore y avoir de l'héritage derrière (et donc de nouvelles méthodes).

Reply

Marsh Posté le 16-03-2006 à 11:09:02    

ton design doit pas etre bon

Reply

Marsh Posté le 16-03-2006 à 11:13:20    

écoute, si tu compiles "x->pouet()" alors pouet doit être déclaré à la compilation.
 
avec ton système, si je fais un plugin avec une méthode x->pilu() :
- comment fait-on pour l'appeler ?
- qui décide de l'appler ?
- elle est appelée comment ?  
 
 
c'est pas la peine de faire de l'héritage si tu fais pas de polymorphisme. Un plugin, c'est un bout de code chargeable à la demande qui fournit une interface. Si quelque chose n'est pas dans l'interface, ça n'est pas utilisable.

Reply

Marsh Posté le 16-03-2006 à 11:28:37    

J'ai pas dit que j'avais bien écrit mon bordel.
Je vous dit que ce que j'ai écrit ne marche pas pour ce que je veux, et j'aimerais trouver un moyen de faire ce que je veux.
Alors avez-vous une idée ?

Reply

Marsh Posté le 16-03-2006 à 11:33:20    

le réécrire de la bonne manière [:spamafote]

Reply

Marsh Posté le 21-08-2006 à 10:27:11    

J'ai l'impression que tu pourrais résoudre ton probleme grace au design pattern Visitor.
http://en.wikipedia.org/wiki/Visitor_pattern
 
la seule chose que tu as à rajouter dans ta classe mère est la fonction accept(Visitor *), en virtual, bien entendu.
Ensuite tu cré une classe abstraite Visitor qui à une methode visit() par classe de ton design (classe A, B, C). Chaque méthode visit prendra une classe différente.
Et dans le accept de chacune des classes, tu mets ce que tu veux mettre...
Tu pourrais donc faire une classe VisitorInitPlugin qui initialise chacun des plugins, par exemple...
 
Je suis pas sûr que le design colle parfaitement à ton probleme, mais ça vaut peut être le coup d'essayer! :)
 
Edit> je viens de voir cela sur dlopen et le C++, c'est assez intéressant... http://www.tldp.org/HOWTO/C++-dlopen/theproblem.html


Message édité par Creak le 21-08-2006 à 10:35:33
Reply

Marsh Posté le 21-08-2006 à 10:27:11   

Reply

Marsh Posté le 21-08-2006 à 10:51:41    

visitor ça change rien. Il faut appeler la même méthode A::accept. Tu pouras jamais appelé B::machin ...

Reply

Marsh Posté le 21-08-2006 à 12:08:07    

RTTI ? (j'ai pas dit que c'était beau :o)

Reply

Sujets relatifs:

Leave a Replay

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