szpryc
szpryc

Reputation: 21

How to get class member function pointer

For one class I want to store some function pointers to member functions of another class. I am trying to return a class member function pointer. Is it possibile?

class one{
public:
  void x();
  void y();
};
typedef void(one::*PF)(void);

class two :public one{
public:
  virtual PF getOneMethodPointer();
};

class three : public two{
  std::vector<PF> pointer_to_function;
  PF getOneMethodPointer();
    pointer_to_function.push_back(getOneMethodPointer())? //how to get method x from class one?
};

Upvotes: 0

Views: 303

Answers (2)

psliwa
psliwa

Reputation: 1092

In C++11/14, you can always use std::function wrapper to avoid writing unreadable and old C-style function pointers. Here's a simple program with this approach:

#include <iostream>
#include <functional>

using namespace std;

class one {
public:
    void x() {  cout << "X called" << endl; }
    function<void()> getOneMethodPointer();
};

class two : public one {
public:
    function<void()> getOneMethodPointer() {
        return bind(&one::x, this);
    }
};

int main()
{
    two* t = new two();
    t->getOneMethodPointer()();
    delete t;
    return 0;
}

As you can see, there's also std::bind used to bind method with std::function. First argument is a reference to the x() method and the second one specifies to which concrete (instantiated) object the pointer is meant to point. Note, that if you say to the st::bind "hey, bind me x() method from one class", it still doesn't know where it is. It knows that - for instance - x() method in this object can be found 20 bytes next to its beginning. Only when you add that it is from for example two* t; object, the std::bind is able to locate the method.


EDIT: Answering to your questions in comments: below code shows an example with virtual getMethodPointer() method:

#include <iostream>
#include <functional>

using namespace std;

class one {
public:
    void x() {  cout << "X called (bound in one class)" << endl; }
    void y() {  cout << "Y called (bound in two class)" << endl; }
    virtual function<void()> getMethodPointer() {
        return bind(&one::x, this);
    }
};

class two : public one {
public:
    virtual function<void()> getMethodPointer() {
        return bind(&one::y, this);
    }
};

int main()
{
    one* t_one = new one();
    one* t_two = new two();
    t_one->getMethodPointer()();
    t_two->getMethodPointer()();
    delete t_one;
    delete t_two;
    return 0;
}

Upvotes: 1

The C++ syntax for it is this:

class two: public one{
  virtual PF getOneMethodPointer(){
    return &one::x;
  }
};

[Live example]

Upvotes: 1

Related Questions