首页 > 解决方案 > 将成员函数作为参数传递错误:“必须调用对非静态成员函数的引用”

问题描述

我是 C++ 新手,想知道如何将一个类的成员函数传递给另一个以函数指针作为参数的函数。对于我尝试的代码,我收到“必须调用对非静态成员函数的引用”的错误。

编辑:将函数设为静态可以解决问题,但是我将无法访问类中定义的变量。

file.cpp:

#include "fooHdr.h"
class bar {
    void clbck() 
    {
       // Do something 
    }
    void init()
    {
        foo(clbck()); 
    }
};
fooHdr.h:
void foo(void (*hndlr)()); 
fooHdr.c
void foo(void (*hndlr)()) { };

标签: c++

解决方案


成员函数指针不同于普通函数指针。一个普通的函数指针如下所示:

void foo() {}

void (*Func)() = foo;    // Function pointer.

成员函数指针如下所示:

class MemberTest {
public:
    void foo() {}
};

void (MemberTest::*Func)() = &MemberTest::foo;  // Member function pointer. Notice the '&' operator here.

int main()
{
    MemberTest test;
    (test.*Func)();    // This is how to call member function pointers.
}

因此,对于您的问题,您需要将其定义为成员函数指针,而不是像普通函数指针:

void foo(void (bar::*hndlr)()); 

并且在调用foo()函数时,必须返回成员函数的地址:

void init()
{
    foo(&bar::clbck); 
}

但是,您仍然不能foo()像这样调用该函数,因为它没有bar对象的当前实例。所以我们必须创建另一个参数来获取指向当前对象的指针:

void foo(bar* pBar, void (bar::*hndlr)()); 
...
foo(this, &bar::clbck); 

所以现在,当从 调用成员函数时foo(),你可以这样做:

(pBar->*hndlr)();

注意:在函数顶部添加前向声明,foo()否则编译器可能会抱怨说bar未定义。


推荐阅读