c++ - 向上转换函数指针安全吗?

标签 c++ pointer-to-member upcasting

我有基类 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/

相关文章:

c++ - 我应该使用高分辨率时间类型作为参数来避免duration_casts吗?

c# - HRESULT 怎么会出现在 MIDL 文件中?

c++ - 寻找更好的编码和压缩数字的方法

android - qt的QSettings访问android中的SharedPreferences

C# 使用对成员函数的委托(delegate)来创建新线程

c++ - 成员函数作为 map 比较器?

c++ - 仅用于向上转换

c++ - 成员函数指针的模板类型推导

Java传递变量——向下转型

java - 涉及通配符的赋值的实际应用是什么?