37

I have class like so

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

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

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?

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

4 Answers 4

42

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);
Sign up to request clarification or add additional context in comments.

Comments

12

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

Comments

5

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); };
}

Comments

2

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);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.