简体   繁体   中英

Get a pointer to object's member function

Here is the problem:

1) I have a class like so:

class some_class
{
public:
    some_type some_value;
    int some_function(double *a, double *b, int c, int d, void *e);
};

2) Inside some_function , I use some_values from some_class object to get a result.

3) So, I have a concrete object and I want to get a pointer to this object some_function .

Is it possible? I can't use some_fcn_ptr because the result of this function depends on the concrete some_value of an object.

How can I get a pointer to some_function of an object? Thanks.

typedef  int (Some_class::*some_fcn_ptr)(double*, double*, int, int, void*);

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.

While not exactly what you requested, if you can use C++11 the following might nevertheless suit your needs (untested):

std::function<int(double*, double*, int, int, void*)>
  some_function_of(Some_class& obj)
{
  return [&](double* a, double* b, int c, int d, void* e){
    return obj.some_func(a, b, c, d, e); };
}

I used the Boost library. I included "boost/bind.hpp" in my code. Then a method named "fn" can be defined as

auto fn = boost::bind(ClassName::methodName, classInstanceName, boost::placeholders::_1);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM