基类的函数指针指向子类的成员函数?

Posted

技术标签:

【中文标题】基类的函数指针指向子类的成员函数?【英文标题】: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)'

【问题讨论】:

【参考方案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 代码经过我的修改后编译并运行良好。

以上是关于基类的函数指针指向子类的成员函数?的主要内容,如果未能解决你的问题,请参考以下文章

为啥指向基类的派生类指针可以调用派生类成员函数? [复制]

获取指向基类受保护成员函数的函数指针

基类与派生类的指针和成员函数调用原理

c++ 虚函数 如何调父类 而非子类

继承与多态C++:继承中的赋值兼容规则,子类的成员函数,虚函数(重写),多态

c++,虚函数的作用,承接上一篇随笔