我尝试使用函数指针( fnPtr )从另一个类方法中引用类方法( fnEmpty ),(在本例中为构造函数)。
安装程序 main.cpp 是
#include <iostream>
#include "test.hpp"
int main(int argc, char* argv[]){
Test test;
return 0;
}
和 test.hpp 读取
#ifndef _test_h
#define _test_h
#include <iostream>
class Test {
private:
public:
void (*ptrEmpty)(void);
void fnEmpty(){ std::cout << "Got Here" << std::endl;};
Test(){ ptrEmpty = fnEmpty; };
~Test(){};
};
#endif
网络细节上的大多数材料都能够引用课堂外的类方法(参见microsoft page和newty.de),而不是来自在课堂内(正如我所做的那样)。
使用上述文件会出现错误
main.cpp中包含的文件:6: ./test.hpp:11:21:错误:必须调用非静态成员函数的引用;
所以 1)为什么会出现此错误?
如果我将第10行的 fnPtr 声明更改为静态,那么它会读取
static void fnEmpty(){ std::cout << "Got Here" << std::endl;};
这似乎解决了这个问题。但这引出了一个问题 2)为什么它接受一个静态的&#39;如果错误只显示非静态&#39;允许吗?
如果我删除了静态而改为第11行(通过添加&amp; ),那么它就会显示
Test(){ ptrEmpty = &fnEmpty; };
我收到一个全新的错误,内容为
./test.hpp:11:21: error: must explicitly qualify name of member function when taking its address
不幸的是替换为
Test(){ Test::ptrEmpty = Test::&fnEmpty; };
或者不包括上面给出的链接中的 Test :: 前缀的变体无法解决问题。
我的印象是,就函数指针而言,在引用函数时(例如 fn ),
ptr = fn;
相当于
ptr = &fn;
3)当我包含并排除&#39;&#39;
时,为什么会出现两组不同的错误?所以我的最终问题是::
4)指向类方法的正确方法是什么(在同一个类的不同方法中)?我是否需要包含&#39; Classname ::&#39;限定符何时属于同一类?
谢谢, 杰夫
答案 0 :(得分:5)
fnEmpty
是一个非静态成员函数,这意味着它接受一个隐式的第一个参数,一个指向它被调用的Test
实例的指针(this
指针)。所以指向该成员函数的指针类型是
void (Test::*ptrEmpty)();
接下来,要形成指向成员函数的指针,您需要使用语法&ClassName::MemFnName
因此,在构造函数中
ptrEmpty = &Test::fnEmpty;
现在你的例子应该编译。您可以使用
调用ptrEmpty
指向的函数
Test t;
(t.*(t.ptrEmpty))();
当您将fnEmpty
更改为static
时,它不再接收隐式this
指针参数,因此它就像任何其他指向函数的指针一样,并且您的代码会编译。