Interesting event handler discussion
Brian Vanderburg II
BrianVanderburg2 at aim.com
Sat Jan 5 01:51:26 PST 2008
This is just for discussion. While I was playing around with some C++
code, I found a possible situation that could on some systems/target
devices break the event handling code, though it has not yet done so.
In C++, there is no specification that says a derived object is at the
same address of the parent object, so in the code:
class MyEvent : public wxEvent...
MyEvent e;
There is no guarantee that (MyEvent*)&e == (wxEvent*)&e
The base event handler contains pointer to members that receive a
wxEvent reference, though the real function usually expects a derived
class, such as wxMouseEvent. Normally, when calling a function passing
a base pointer to a parameter that excepts a derived pointer, it will
properly convert it if an explicit cast is given;
Base* b;
CallFunction((Derived*)b) Will convert the pointer value if they the
base and derived are not at the same address.
After some testing, it seems that the pointer-to-member-function does
not store any adjustment information for parameters. That is to say:
void (MyObject::*f1)(wxMouseEvent& evt);
void (BaseObject::*f2)(wxEvent& evt);
f1 = MyObject::OnMouseMove
f2 = (void (BaseObject::)(wxEvent&))f1;
When assigning from f1 to f2, it will store any adjustments needed in
the pointer-to-member-function so that a pointer to BaseObject will be
correct converted to a pointer to MyObject when calling the function
though f2. However, it does not store any adjustments to convert from
wxEvent to wxMouseEvent. This does not cause a problem because in
single inheritance, the derived object normally has the same address as
the base object. But I believe multiple inheritance would break it
entirely:
class wxJunk
{
int some;
int data;
int to;
int take;
int up;
int space;
};
class wxMouseEvent : public wxJunk : public wxEvent
{
}
If the mouse event looked like this, then doing:
(obj->*fn)(evt)
Would cause problems. The target function expects a wxMouseEvent
reference, but a wxEvent reference is being passed instead. Since the
pointer-to-member does not store adjustments for parameters, but only
the adjustment to convert 'this' from the class type that the member
pointer is to the class type the target function expects, it does not
convert the argument.
Again this is only something I found interesting to find out, as long
as events are 'single inheritance' only and the compilers keep the
derived and base addresses aligned ((Derived*)f == (Base*)f), it should
be fine.
Brian Vanderburg II
More information about the wx-users
mailing list