By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
445,778 Members | 1,919 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 445,778 IT Pros & Developers. It's quick & easy.

Pointer-to-member-function pointing to a member function of an inherited class

P: n/a
The subject basically says what I am having trouble with. For an
example lets say I have a class A which has a function f. I then also
have a class B which inherits from A and has a function g.

class A
{
public: void f(int,float);
};

class B : public A
{
public: void g(int, float);
};
Okay, now with all that setup, if I created a pointer to a member
function something like this:

typedef void (A::*MFP)(int a, float b);

if I then use it such as

MFP mfp = &A::f;

then everything works fine.

even if I do:

MFP mfp2 = &B::f;

then everything still works (presumably because f is not defined in B
and must then be from A). However, if I try this:

MFP mfp3 = &B::g;

then it complains that B::g is not of the right type since it is not a
member function of class A. The protype signature is the same, both
(int, float), is there no way to make this work? It seemed to me that
it should have worked since any instance of B is still by definition an
instance of A. Anyone done anything like this?

-akiriwas

Jul 23 '05 #1
Share this Question
Share on Google+
12 Replies


P: n/a
ak******@gmail.com wrote:
The subject basically says what I am having trouble with. For an
example lets say I have a class A which has a function f. I then also
have a class B which inherits from A and has a function g.

class A
{
public: void f(int,float);
};

class B : public A
{
public: void g(int, float);
};
Okay, now with all that setup, if I created a pointer to a member
function something like this:

typedef void (A::*MFP)(int a, float b);
Try making this :

typedef void (B::*MFP)(int a, float b);

if I then use it such as

MFP mfp = &A::f;

then everything works fine.

even if I do:

MFP mfp2 = &B::f;
&B::f becomes &A::f when the compiler is done with it because f is a
member of A - this is some magic specified by the standard and only
works with literal pointer to members.

An A::* member pointer can be converted to a B::* member pointer but not
the other way. i.e.

typedef void (A::*AMFP)(int a, float b);
typedef void (B::*BMFP)(int a, float b);
void f( AMFP a, AMFP b )
{
b = a; // legal
a = b; // illegal
}

then everything still works (presumably because f is not defined in B
and must then be from A). However, if I try this:

MFP mfp3 = &B::g;
Think about it - an object of type A can't really support a method of
class B since it's impossible to really which type of object you really
have.

then it complains that B::g is not of the right type since it is not a
member function of class A. The protype signature is the same, both
(int, float), is there no way to make this work? It seemed to me that
it should have worked since any instance of B is still by definition an
instance of A. Anyone done anything like this?


Yes.

options for this case are:

a) use virtual methods
b) use functions (not member functions)
Jul 23 '05 #2

P: n/a

<ak******@gmail.com> wrote in message
news:11**********************@f14g2000cwb.googlegr oups.com...
The subject basically says what I am having trouble with. For an
example lets say I have a class A which has a function f. I then also
have a class B which inherits from A and has a function g.

class A
{
public: void f(int,float);
};

class B : public A
{
public: void g(int, float);
};
Okay, now with all that setup, if I created a pointer to a member
function something like this:

typedef void (A::*MFP)(int a, float b);

if I then use it such as

MFP mfp = &A::f;

then everything works fine.

even if I do:

MFP mfp2 = &B::f;

then everything still works (presumably because f is not defined in B
and must then be from A). However, if I try this:

MFP mfp3 = &B::g;

then it complains that B::g is not of the right type since it is not a
member function of class A.
Correct.
The protype signature is the same,
Same as what? You seem to think that a 'B' object has
more than one function named 'g'. There is only one,
the member of 'A' (which is a member of 'B') .
both
(int, float), is there no way to make this work? It seemed to me that
it should have worked since any instance of B is still by definition an
instance of A.
But 'g' is still only a member of 'A', it's not a member of 'B'.
When you derive 'B' from 'A', 'A' is *contained* by 'B'. There
is no 'duplication' of members. A 'B' object will have two
'parts': the 'A' part, and the 'part' containing any members
defined only in 'B' (if any).

What are you trying to do that you think you can't using
&A::g ??
Anyone done anything like this?


No, because there's no need. What specifically are you
trying to do?

-Mike

Jul 23 '05 #3

P: n/a
Look at this way with different names:
1) a Person has a name
2) a Student has a name
3) but not every Person has a grade.

class Person
{
public:
void name(int,float);
};
class Student : public Person
{
public:
void grade(int, float);
};

int main() {

typedef void (Person::*MFP)(int a, float b);

MFP mfp1 = &Person::name;
MFP mfp2 = &Student::name;
MFP mfp3 = &Student::grade;
return 0;
}

Jul 23 '05 #4

P: n/a

akiri...@gmail.com wrote:
The subject basically says what I am having trouble with. For an
example lets say I have a class A which has a function f. I then also have a class B which inherits from A and has a function g.

class A
{
public: void f(int,float);
};

class B : public A
{
public: void g(int, float);
};
Okay, now with all that setup, if I created a pointer to a member
function something like this:

typedef void (A::*MFP)(int a, float b);

This means you can call an MFP function with an object of type A.

if I then use it such as

MFP mfp = &A::f;

then everything works fine.

even if I do:

MFP mfp2 = &B::f;

then everything still works (presumably because f is not defined in B
Yes, because you can call f(...) using an object of type A. A and B
are of type A.

and must then be from A). However, if I try this:

MFP mfp3 = &B::g;

then it complains that B::g is not of the right type since it is not a member function of class A.


This will not work, because you cannot call g(...) using all objects of
type A. A pointer to 'A' is not necessarily an object of type B, so if
I have class C, which also derives from A, I must not be able to call
g(...) using an object of type C.

-shez-

Jul 23 '05 #5

P: n/a
Basically, I have a base class, I want to be able to be able to have
keep a list of pointers to member functions such that they all have the
same type. For instance somefunction(int, float). But I also want
someone else to be able to subclass the baseclass, create their own
member function with the same type, for instance someotherfunction(int,
float) and have the function pointer still be able to point to it.
-akiriwas

Jul 23 '05 #6

P: n/a
This is exactly what I'm trying to do in the case you have with MFP
mfp3 = &Student::grade. However, when I compile the exact code you
show with g++ it gives me the error

error: cannot convert `void (Student::*)(int, float)' to `void
(Person::*)(int, float)' in initialization
Did the code you wrote work for you?

-akiriwas

Jul 23 '05 #7

P: n/a

ak******@gmail.com wrote:
Basically, I have a base class, I want to be able to be able to have
keep a list of pointers to member functions such that they all have the same type. For instance somefunction(int, float). But I also want
someone else to be able to subclass the baseclass, create their own
member function with the same type, for instance someotherfunction(int, float) and have the function pointer still be able to point to it.
-akiriwas


This is simply not possible.

class A { ... };
class B : public A { ... };
class C : public A { ... };

A a;
B b;
C c;

If I have a function pointer to a method in class A, I am guaranteed to
be able to call that function using any object derived from A (that
means I can use it with 'a', 'b', and 'c').

It *cannot* point to a method in class B. What would happen if I call
the function using 'c'??

Pls let us know why you are trying to do this. There is probably a
much better, more elegant, solution instead of using function pointers.
-shez-

Jul 23 '05 #8

P: n/a

Shezan Baig wrote:

class A { ... };
class B : public A { ... };
class C : public A { ... };

A a;
B b;
C c;

If I have a function pointer to a method in class A, I am guaranteed to be able to call that function using any object derived from A (that
means I can use it with 'a', 'b', and 'c').

It *cannot* point to a method in class B. What would happen if I call the function using 'c'??

Or even 'a'??


Pls let us know why you are trying to do this. There is probably a
much better, more elegant, solution instead of using function pointers. -shez-


Jul 23 '05 #9

P: n/a
No, it does not work. I was trying to demonstrate intuitively that it's
incorrect.

Jul 23 '05 #10

P: n/a
Okay.. I get it now. Well, you definitely hit the nail on the head for
what I was trying to do, but obviously now cannot. Are there any
suggestions on what I can do to do something like it? By the way,
thanks for the help so far.

-akiriwas

Jul 23 '05 #11

P: n/a

ak******@gmail.com wrote:
Okay.. I get it now. Well, you definitely hit the nail on the head for what I was trying to do, but obviously now cannot. Are there any
suggestions on what I can do to do something like it? By the way,
thanks for the help so far.

-akiriwas


You probably want to use virtual functions. For example:

class A {
public:
virtual void mfp(int a, double b)
{
doSomething(...);
}
};

class B : public A {
public:
virtual void mfp(int a, double b) // overriding A::mfp(...)
{
doSomethingElse(...);
}
};

A a;
B b;

A *pA1 = &a;
A *pA2 = &b;

pA1->mfp(...); // will call A::mfp(...)
pA2->mfp(...); // will call B::mfp(...)

Hope this helps,
-shez-

Jul 23 '05 #12

P: n/a
All the other fellows said I agree, but you
can also do exactly what you want by doing:

MFP mfp3 = (MFP) &B::g;

Took me forever to get this right, but it is
a very useful technique. I have a simple
base class A with nothing. Then I have lots of
different methods that do various different things on many different
classes B, C that are derived
from A. If I add stuff to class B and allow the
proper pointers to be set, I don't want to
go back to A and add one more virtual class.
Besides C also inherited from A might have
a whole different set of functions.

The only thing you have to be cautious
about is to make sure when you're invoking a
particular function, as with any typecast,
is that the particular object supports that
particular function. I usually keep both the
pointer to the object and the pointer to the
function together to make sure that this is done
right. You can also dynamic cast to make sure
you're point to a B object before you do the
->* function call

-Fluden
(from Porto Alegre, Brazil)

Jul 23 '05 #13

This discussion thread is closed

Replies have been disabled for this discussion.