【问题标题】:Base class's function pointer points to child class's member function?基类的函数指针指向子类的成员函数?
【发布时间】:2010-10-13 01:10:46
【问题描述】:

我知道这听起来很令人困惑,我有一个基模板类,它有一个函数指针,一个子类(不再是模板类)需要使用该函数指针指向子类的成员函数,并且我得到了各种各样的错误..我违反了 C++ 的一些普遍规律吗? 这是伪代码:

template <class T>
class Base{
    public:
       typedef void (Base<T>::*fptr) (char in);
       void funcA(fptr FuncToCall){
                 FuncToCall('a');
       }
       ...
    };

class Child:public Base<char>{
   public: 
       void funcToCall(){...}
       void funcB(){
          funcA(funcToCall);
       }
}

这是我收到的错误消息:

错误 C2664: 'Base::funcA' : 不能 将参数 1 从 'void (__thiscall Child::* )(char)' 到 'void (__thiscall Base::*)(char)'

【问题讨论】:

    标签: c++ inheritance function-pointers


    【解决方案1】:

    您的代码无效。

    首先,在 C++ 中,要创建指向成员函数的指针,您总是必须使用运算符 &amp; 和成员的限定名称,这意味着您对 funcA 的调用应该如下所示

    funcA(&Child::funcToCall); // close, but not yet, see "secondly" 
    

    其次,成员指针是逆变的。如果要使用派生成员指针值初始化基成员指针对象,则必须使用显式static_cast

    funcA(static_cast<fptr>(&Child::funcToCall));
    

    请注意,这是一种有效但可能不安全的转换,因为您现在有责任确保调用左侧(参见“第三部分”)使用的实际对象具有该成员。

    第三,为了通过这样的指针调用函数,你必须在左侧提供一个具体的对象,所以funcA中的调用应该如下所示(我假设你想调用它对于*this 对象)

    (this->*FuncToCall)('a');
    

    第四,你的funcToCall 应该有一个参数。它在哪里?

    【讨论】:

    • 谢谢,我试过了,我得到这个错误:(类似于第一个)错误 C2664:'Base::funcA' : cannot convert parameter 1 from 'void (__thiscall Child: :fptr )(char)' 到 'void (__thiscall Base::* )(char)'
    • @Yonk:请注意。要么你忘记添加static_cast,如我的“第二个”所示,要么你正在编译不同的代码。
    • 是的,我添加了,仍然得到类似的错误。唯一的区别是 Child::* 变成了 Child::fptr
    • @Yonk:这意味着您更改了原始版本的代码。我不是心灵感应,我不知道你还对它做了什么。您的 original 代码经过我的修改后编译并运行良好。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-07-27
    • 2013-06-06
    • 1970-01-01
    • 1970-01-01
    • 2015-11-18
    • 2010-10-01
    相关资源
    最近更新 更多