使用函数指针没有任何问题。但是,指向非静态成员函数的指针与普通函数指针不同:成员函数需要在作为隐式参数传递给函数的对象上调用。上面的成员函数的签名是,因此
void (aClass::*)(int, int)
而不是您尝试使用的类型
void (*)(int, int)
一种方法可能是创建成员函数static
,在这种情况下,它不需要调用任何对象,您可以将它与 type 一起使用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, nullptr);
foo object;
somefunction(&forwarder, &object);
}