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