There isn't anything wrong with using function pointers. However, pointers to non-static member functions are not like normal function pointers: member functions need to be called on an object which is passed as an implicit argument to the function. The signature of your member function above is, thus
void (aClass::*)(int, int)
rather than the type you try to use
void (*)(int, int)
One approach could consist in making the member function static
in which case it doesn't require any object to be called on and you can use it with the type void (*)(int, int)
.
If you need to access any non-static member of your class and you need to stick with function pointers, e.g., because the function is part of a C interface, your best option is to always pass a void*
to your function taking function pointers and call your member through a forwarding function which obtains an object from the void*
and then calls the member function.
In a proper C++ interface you might want to have a look at having your function take templated argument for function objects to use arbitrary class types. If using a templated interface is undesirable you should use something like std::function<void(int, int)>
: you can create a suitably callable function object for these, e.g., using std::bind()
.
The type-safe approaches using a template argument for the class type or a suitable std::function<...>
are preferable than using a void*
interface as they remove the potential for errors due to a cast to the wrong type.
To clarify how to use a function pointer to call a member function, here is an example:
// 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 << "
";
}
struct foo {
void member(int i0, int i1) {
std::cout << "member function: this=" << this << " i0=" << i0 << " i1=" << i1 << "
";
}
};
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);
}