功能指针(类内)

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 pagenewty.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 ::'限定符?

谢谢,杰夫

Pra*_*ian 5

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)

当你更改fnEmptystatic它不再接收隐式this指针参数时,它就像任何其他指向函数的指针一样,并且你的代码会编译.