Get a pointer to object's member function
You cannot, at least it won't be only a pointer to a function.
Member functions are common for all instances of this class. All member functions have the implicit (first) parameter, this
. In order to call a member function for a specific instance you need a pointer to this member function and this instance.
class Some_class
{
public:
void some_function() {}
};
int main()
{
typedef void (Some_class::*Some_fnc_ptr)();
Some_fnc_ptr fnc_ptr = &Some_class::some_function;
Some_class sc;
(sc.*fnc_ptr)();
return 0;
}
More info here in C++ FAQ
Using Boost this can look like (C++11 provides similar functionality):
#include <boost/bind.hpp>
#include <boost/function.hpp>
boost::function<void(Some_class*)> fnc_ptr = boost::bind(&Some_class::some_function, _1);
Some_class sc;
fnc_ptr(&sc);
C++11's lambdas:
#include <functional>
Some_class sc;
auto f = [&sc]() { sc.some_function(); };
f();
// or
auto f1 = [](Some_class& sc) { sc.some_function(); };
f1(sc);
You may write some kind of Wrapper which is able to use both function or method as parameter.
I used following classes for launching functions (it was used in one my SDL program):
class CallbackFunction {
public:
// Constructor, copy constructor and destructor
virtual int execute( SDL_keysym* keysym) const;
virtual int operator()( SDL_keysym* keysym) const;
protected:
int( *callback)( SDL_keysym*));
}
int CallbackFunction::execute( SDL_keysym* keysym) const{
return callback(keysym);
}
int CallbackFunction::operator()( SDL_keysym* keysym) const{
return callback( keysym);
}
And this extension for "methods":
template<class T>
class CallbackMethod : public CallbackFunction {
public:
// Constructor, copy constructor and destructor
CallbackMethod( T *object, int(T::*callback)( SDL_keysym* keysym));
int execute( SDL_keysym* keysym) const;
int operator()(SDL_keysym* keysym) const;
protected:
T *object;
int(T::*method)( SDL_keysym* keysym);
};
// Object initialization (constructor)
template<class T>
CallbackMethod<T>::CallbackMethod( T *object, int(T::*callback)( SDL_keysym* keysym)):
CallbackFunction( NULL),object(object),method(callback){
}
// Responsible for executing
template<class T>
int CallbackMethod<T>::execute( SDL_keysym* keysym) const {
return (object->*method)(keysym);
}
template<class T>
int CallbackMethod<T>::operator()( keysym) const {
return (object->*method)( keysym);
}
And then use it as:
CallbackFunction *callback;
callback = new CallbackFunction( myFunction);
callback = new CallbackMethod<A>( instanceOfA, instanceOfA::myMethod);
callback = new CallbackMethod<B>( instanceOfB, instanceOfB::myMethod);
...
callback( keysym);
I found macro as this:
CALLBACK(object,method) new CallbackMethod<typeof(*object)>( object, &method)
really useful
No, you can't get a pointer to a C++ class method (unless the method is declared static). The reason is that a class method always has the pointer this
, a pointer to the class instance. But were you to call the method through a pointer, that pointer could not encapsulate the this
pointer, and then then there would be no instance attached, and therefore this behavior is not legal.