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