I have base classes Object and an Event
class Object
{
//...
};
class Event
{
};
And a typedef for a function pointer
typedef void (Object::*PF) (Event*);
And an unrelated class which stores two pointers
class Dispatcher
{
public:
Dispatcher (Object* obj, PF pf) : _obj (obj), _pf (pf)
void call (Event* event)
{
_obj->*pf (event);
}
Object* _obj;
PF _pf;
};
I then have a concrete object and a concrete event
class ConcreteEvent : public Event
{
};
class ConcreteObject : public Object
{
public:
void handle (ConcreteEvent* event)
{
// Do something specific for ConcreteEvent
}
};
And then call it like this
ConcreteObject* obj = new ConcreteObject();
Dispatcher dispatcher (obj, static_cast<PF>(&ConcreteObject::handle));
ConcreteEvent* event = new ConcreteEvent ();
dispatcher.call (event);
I guarantee that the dispatcher will always be called with a correct event, i.e. I will not call a dispatcher and pass it ConcreteEvent when the function pointer it encapsulates in fact takes SomeOtherConcreteEvent
The question is: Is this guaranteed to work? Is certainly works fine in gcc 4.7 on both linux and mingw.
From the C++11 standard, section 4.11.2:
A prvalue of type “pointer to member of B of type cv T”, where B is a class type, can be converted to a prvalue of type “pointer to member of D of type cv T”, where D is a derived class (Clause 10) of B. If B is an inaccessible (Clause 11), ambiguous (10.2), or virtual (10.1) base class of D, or a base class of a virtual base class of D, a program that necessitates this conversion is ill-formed. The result of the conversion refers to the same member as the pointer to member before the conversion took place, but it refers to the base class member as if it were a member of the derived class.
So yes, this should be safe.
Edit: so if you actually meant downcasting: that's also legal, according to C++11 5.2.9.12:
A prvalue of type “pointer to member of D of type cv1 T” can be converted to a prvalue of type “pointer to member of B” of type cv2 T, where B is a base class (Clause 10) of D, if a valid standard conversion from “pointer to member of B of type T” to “pointer to member of D of type T” exists (4.11), and cv2 is the same cv-qualification as, or greater cv-qualification than, cv1. 69
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With