使用函数指针没有任何问题。但是,指向非静态成员函数的指针与普通函数指针不同:成员函数需要在作为隐式参数传递给函数的对象上调用。因此,您上面的成员函数的签名是
void (aClass::*)(int, int)
而不是您尝试使用的类型
void (*)(int, int)
一种方法可能是制作成员函数,static
在这种情况下,不需要调用任何对象,并且可以将其与类型一起使用void (*)(int, int)
。
如果您需要访问类的任何非静态成员, 并且需要坚持使用函数指针,例如,由于该函数是C接口的一部分,则最好的选择是始终将a传递给带有void*
函数指针的函数并调用您的成员通过转发函数从中获取对象void*
,然后调用该成员函数。
在适当的C ++接口中,您可能需要看一下让函数采用模板化参数的函数对象,以使用任意类类型。如果不希望使用模板化接口,则应使用类似以下内容的方法std::function<void(int, int)>
:您可以为这些创建合适的可调用函数对象,例如,使用std::bind()
。
使用模板参数作为类类型或适当类型的类型安全方法std::function<...>
比使用void*
接口因为它们消除了由于转换为错误类型而导致的错误可能性。
为了阐明如何使用函数指针来调用成员函数,下面是一个示例:
// 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);
}