在C ++中传递成员函数作为参数

可能重复:
C ++,成员函数的函数指针

问题是以下几点:考虑这段代码:

#include <iostream> class aClass { public: void aTest(int a, int b) { printf("%d+%d=%d",a,b,a+b); } }; void function1(void (*function)(int,int)) { function(1,1); } void test(int a,int b) { printf("%d-%d=%d",a,b,ab); } int main (int argc, const char * argv[]) { aClass a(); function1(&test); function1(&aClass::aTest ); // <-- how should I point to a's aClass::test function? return 0; } 

我如何使用aaClass::test作为function1的参数? 我坚持这样做。

我想访问该课程的成员。

使用函数指针没有任何问题。 但是,指向非静态成员函数的指针不像普通的函数指针:成员函数需要在作为函数的隐式parameter passing的对象上调用。 因此,上面的成员函数的签名是

 void (aClass::*)(int, int) 

而不是您尝试使用的types

 void (*)(int, int) 

一种方法可能在于使成员函数是static在这种情况下,它不需要调用任何对象,并且可以将它与void (*)(int, int)types一起使用。

如果你需要访问你的类的任何非静态成员,你需要坚持使用函数指针,例如,因为函数是C接口的一部分,最好的select是总是传递一个void*到函数指针并通过从void*获取对象的转发函数调用您的成员,然后调用成员函数。

在一个合适的C ++接口中,你可能想看看让你的函数使用任意类types的函数对象的模板参数。 如果使用模板化的接口是不可取的,你应该使用像std::function<void(int, int)> :你可以为它们创build一个适当的可调用函数对象,例如使用std::bind()

对于类types或适当的std::function<...>使用模板参数的types安全方法优于使用void*接口,因为它们消除了由于转换为错误types而可能发生的错误。

为了阐明如何使用函数指针来调用成员函数,下面是一个例子:

 // the function using the function pointers: void somefunction(void (*fptr)(void*, int, int), void* context) { fptr(context, 17, 42); } void non_member(void*, int i0, int i1) { std::cout << "I don't need any context! i0=" << i0 << " i1=" << i1 << "\n"; } struct foo { void member(int i0, int i1) { std::cout << "member function: this=" << this << " i0=" << i0 << " i1=" << i1 << "\n"; } }; void forwarder(void* context, int i0, int i1) { static_cast<foo*>(context)->member(i0, i1); } int main() { somefunction(&non_member, 0); foo object; somefunction(&forwarder, &object); } 

@Pete贝克尔的答案是好的,但你也可以做到这一点,而无需将类实例作为显式parameter passing给C ++ 11中的function1

 #include <functional> using namespace std::placeholders; void function1(std::function<void(int, int)> fun) { fun(1,1); } int main (int argc, const char * argv[]) { ... aClass a; auto fp = std::bind(&aClass::test, a, _1, _2); function1(fp); return 0; } 

成员函数的指针与指向函数的指针不同。 为了通过指针使用成员函数,你需要一个指向它的指针(显然)和一个对象来应用它。 所以适当的版本的function1将是

 void function1(void (aClass::*function)(int, int), aClass& a) { (a.*function)(1, 1); } 

并称之为:

 aClass a; // note: no parentheses; with parentheses it's a function declaration function1(&aClass::test, a);