Question

I need to have array of function pointers in base class, and to define this array to point to functions in child classes like this:

typedef double (_f)(int,int);
class A{
public:
  _f **m_arf;
};

class B:public A{
public:
  double get1(int i, int j) {return i+j};
  double get2(int i, int j) {return i-j};
B(){
     m_arf = new _f*[2];
     m_arf[0] = &get1;
     m_arf[1] = &get2;
   };
};

and then I can do the following:

{
  A* pA = new B;
  int ires = pA->m_arf[0](1,2); // returns B::get1(1,2)
  int ires1 = pA->m_arf[1](1,2); // returns B::get2(1,2)
}

Is it possible?

Was it helpful?

Solution

The pointer:

typedef double (_f)(int,int);

Does not/cannot point to a member function. It can only point to a free function. So what you're trying to do will never work the way you're trying to do it.

To declare a member function pointer, the syntax is different:

typedef double (A::*_f)(int,int);

In addition, you also have to take the pointer with different syntax: you must refer to the class.

_f = &B::get1; // not &get1

However, now you'll have another problem, and that is that get1 isn't a member of A, but a member of B. In order to assign a pointer to a member of a derived class to a pointer to a member of a base class, you must use static_cast:

m_arf[0] = static_cast <A::Fn> (&B::get1);

Finally, the syntax to atually call through this pointer is also different. You can't just call through the pointer directly -- you have to also associate the call with an instance of the class. The ->* syntax connects the class instance to the function pointer:

int ires = (pA->*(pA->m_arf [0])) (1,2);

Phew, what a mess. It's really best to not use member function pointers in this way unless you really have to. Regardless, here's a demo of how it's done here.

class A{
public:
  typedef double (A::*Fn) (int, int);
  Fn *m_arf;
};

class B:public A{
public:
  double get1(int i, int j)  
  {
    return i+j;
  };  
  double get2(int i, int j)  
  {
    return i-j;
  };  
B(){
     m_arf = new Fn[2];
     m_arf[0] = static_cast <A::Fn> (&B::get1);
     m_arf[1] = static_cast <A::Fn> (&B::get2);
   };  
};

int main()
{
  A* pA = new B;
  int ires = (pA->*(pA->m_arf [0])) (1,2); // returns B::get1(1,2)
  int ires1 = (pA->*(pA->m_arf[1])) (1,2); // returns B::get2(1,2)
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top