Reputation: 43
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?
Upvotes: 1
Views: 100
Reputation: 101506
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)
}
Upvotes: 1