0

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?
};
szpryc
  • 21
  • 4

2 Answers2

1

The C++ syntax for it is this:

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

[Live example]

Angew is no longer proud of SO
  • 167,307
  • 17
  • 350
  • 455
  • getOneMethodPointer() can return pointer to void x(); method? what type should be getOneMethodPointer() method? – szpryc Jun 25 '15 at 08:39
  • @szpryc Well, you defined it with retun type `PF`, so it should return a `PF` object, such as `&one::x`. That's not much different from returning `42` from a function with return type `int`. You might find it useful to clarify these concepts with the help of a [good book](http://stackoverflow.com/q/388242/1782465). – Angew is no longer proud of SO Jun 25 '15 at 08:43
  • @szpryc I just edited the answer to match the question edit. But you might want to edit the question some more - now you have code outside of a function, which is syntactic nonsense. – Angew is no longer proud of SO Jun 25 '15 at 08:45
  • @szpryc Can you elaborate? How does it "not work?" I've added a live example link to the answer. – Angew is no longer proud of SO Jun 25 '15 at 09:19
1

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;
}
psliwa
  • 1,094
  • 5
  • 9