[C++] Pointeur sur fonctions membres virtuelles
Bonjour à tous,
Je vais essayer d'expliquer clairement mon problème. J'ai une classe de base Tool qui représente un outil sélectionné par l'utilisateur que je dérive en une classe ConcreteTool pour mon exemple. De la même façon, j'ai une classe Event (événement utilisateur) dérivée en MouseDownEvt par exemple auquel mon ConcreteTool réagit. L'idée c'est que chaque événement connait la fonction membre de ConcreteTool à appeller. Chaque Event possède donc un pointeur vers une fonction membre virtuelle de Tool. Voici l'allure de mes classes :
Tool.h
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
|
class Tool
{
public:
Tool(void);
~Tool(void);
virtual void onLeftMouseDown(void* sender, EventArg* e) {}
virtual void onLeftMouseUp(void* sender, EventArg* e) {}
virtual void onLeftMouseDrag(void* sender, EventArg *e) {}
...
};
class ConcreteTool
{
public:
virtual void onLeftMouseDown(void* sender, EventArg* e)
{
std::cout<<test<<std::endl;
}
...
}; |
Event.h
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
class EventArg;
class Tool;
typedef void (Tool::*toolFnPtr)(void*, EventArg*);
class Event
{
protected :
void* sender;
EventArg* arg;
toolFnPtr callback;
public:
Event(void);
~Event(void);
inline void* getSender() const { return sender ; }
inline toolFnPtr getCallback() const { return callback; }
inline virtual EventArg* getArguments() { return arg; }
}; |
Pour créer un événement, je m'y prend comme cela :
Code:
1 2 3 4 5 6 7
|
MouseDownEvt::MouseDownEvt(void *evtSender, const Vect2 &p, ModifierKey key) : Event()
{
sender = evtSender;
arg = new MouseDownEvtArg(p, key);
callback = &Tool::onLeftMouseDown;
} |
Enfin, un gestionnaire traite l'événement ainsi :
Code:
1 2 3 4 5 6 7 8 9
|
void ToolSystem::treatEvent(Event *evt)
{
void* sender = evt->getSender();
EventArg* arg = evt->getArguments();
toolFnPtr fun = evt->getCallback();
(currentTool->*fun)(sender, arg); // CRASH
...
} |
Je compile avec le compilo de vs2005 et comme raison du crash, j'ai droit à un "Acces violation". En observant les adresses avec le débuggueur, j'ai remarque qu'il y avait des différences.
Variable:---------------------Value:-----------------Type
&Tool::onLeftMouseDown-----0x00411b90"U‹ììÌ"-------char *
fun--------------------------0x00356818 ------------void (void *, EventArg *)*
&IdleTool::onLeftMouseDown -0x00411a30"U‹ìjÿh+qA"--char *
Ces adresses sont aussi différentes des adresses de la vtable de currentTool.
Quelqu'un peut-il me dire où ça cloche et comment y remédier ? J'espère avoir été assez clair.
Merci d'avance.