我有基类 Object
和一个 Event
class Object
{
//...
};
class Event
{
};
还有一个函数指针的typedef
typedef void (Object::*PF) (Event*);
还有一个不相关的类,它存储两个指针
class Dispatcher
{
public:
Dispatcher (Object* obj, PF pf) : _obj (obj), _pf (pf)
void call (Event* event)
{
_obj->*pf (event);
}
Object* _obj;
PF _pf;
};
然后我有一个具体的对象和一个具体的事件
class ConcreteEvent : public Event
{
};
class ConcreteObject : public Object
{
public:
void handle (ConcreteEvent* event)
{
// Do something specific for ConcreteEvent
}
};
然后这样调用
ConcreteObject* obj = new ConcreteObject();
Dispatcher dispatcher (obj, static_cast<PF>(&ConcreteObject::handle));
ConcreteEvent* event = new ConcreteEvent ();
dispatcher.call (event);
我保证将始终使用正确的事件调用调度程序,即我不会调用调度程序并传递它 ConcreteEvent
当它封装的函数指针实际上取SomeOtherConcreteEvent
时
问题是:这能保证有效吗?在 linux 和 mingw 上的 gcc 4.7 中当然可以正常工作。
最佳答案
来自 C++11 标准,第 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.
所以是的,这应该是安全的。
编辑:因此,如果您实际上是指向下转型:根据 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
关于c++ - 向上转换函数指针安全吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14961322/