Pointeurs de fonctions et polymorphisme

Pointeurs de fonctions et polymorphisme - C++ - Programmation

Marsh Posté le 04-04-2008 à 17:56:57    

Bonjour, je cherche à savoir si c'est possible de déclarer un function pointer dans une base qui soit utilisable dans les dérivées ; c'est à dire dans l'idée un membre void (Base::*foo)() qui deviendrait un void (Derived::*foo)() selon où il se trouve . Pour l'instant j'ai tenté un boost::function<void(Base*)> qui me donne "cannot convert from Base* to Derived*" quand je m'en sers

Reply

Marsh Posté le 04-04-2008 à 17:56:57   

Reply

Marsh Posté le 05-04-2008 à 23:37:24    

Reply

Marsh Posté le 06-04-2008 à 17:05:44    

Non, pas de static que ce soit le pointeur ou les fonctions que j'y met

Reply

Marsh Posté le 06-04-2008 à 19:07:09    

Je viens de trouver un truc qui a l'air de marcher (je pige pas trop mais bon) :
fptr=static_cast<void ( Base::* )()>(&Derived::Bidule);

Reply

Marsh Posté le 06-04-2008 à 19:27:11    

pointeur de méthode virtuelles ?
Ton cast là c'est ce que génère le compilo avec une méthode virtuelle, le pointeur étant stocké dans une vtable.
 
Et tout cast de pointeur de méthode est non-portable, et nécessite un reinterpret_cast. Rien ne te dis que les pointeurs de Base::* et de Derived::* ont la même longueur. Si Derived hérite de Base par héritage multiple ou virtuel ça sera surement pas le cas d'ailleurs.
 
Si tu veux éviter une méthode virtuelle par souci de perfs (ce dont je te féliciterais au passage) tu peux faire une méthode Bidule et une méthode Bidule_virtual qui apellerait la méthode bidule normale. Ou encore appeller Bidule explicitement avec Base::Bidule ou Derived::Bidule.

Reply

Marsh Posté le 06-04-2008 à 20:42:12    

A vrai dire c'est plus par flemme d'utiliser un pattern state ou strategy, le but est d'avoir un  
std::vector<void (Base::*)()> states;
que chaque dérivée initialise comme elle veut  
states.push_back(reinterpret_cast<void (Base::*)()>(&UneDerivee::Machin));
states.push_back(reinterpret_cast<void (Base::*)()>(&UneDerivee::Truc));
etc
après on fait (*this.*states[currentState])(); ...
En tout cas je ne compte pas avoir d'héritage virtuel ou multiple .

Reply

Marsh Posté le 06-04-2008 à 23:07:24    

Code :
  1. class Base
  2. {
  3. public :
  4.     Base();
  5.     virtual void Machin();
  6.     virtual void Bidule();
  7.     virtual void Truc();
  8. };
  9. class Derived : public Base
  10. {
  11. public :
  12.     Derived();
  13.     virtual void Machin();
  14.     virtual void Bidule();
  15.     virtual void Truc();
  16. };
  17. std::vector< void (Base::*)() > vec;
  18. vec.push_back( &Base::Machin );
  19. vec.push_back( &Base::Bidule );
  20. Base b;
  21. Derived d;
  22. (b.*(vec[0]))(); // appelle Base::Machin()
  23. (b.*(vec[1]))(); // appelle Base::Bidule()
  24. (d.*(vec[0]))(); // appelle Derived::Machin()
  25. (d.*(vec[1]))(); // appelle Derived::Bidule()


 
et aucun cast !

Reply

Marsh Posté le 06-04-2008 à 23:09:22    

(*this.*states[currentState])(); ...  
 
non c'est
 
(this->*states[currentState])();
 
mais ton compilo te l'aurait dit :D

Reply

Sujets relatifs:

Leave a Replay

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