Casting pointer to member

C

cbull

class A
{
};
class B: public A
{
void f();
};

typedef void (A::*MPA)(void);
MPA mpA;

B b;
mpA = (MPA) &B::f;

b->*mpA();


Will it work? If not then when it will fail? I've heard something about
multi inheritance.

Tomasz
 
V

Victor Bazarov

cbull said:
class A
{
};
class B: public A
{
void f();
};

typedef void (A::*MPA)(void);
MPA mpA;

B b;
mpA = (MPA) &B::f;

b->*mpA();


Will it work? If not then when it will fail? I've heard something about
multi inheritance.

No, it won't work. B::f is not a member of A. Pretending that it is will
not help solving whatever problem you're trying to solve. BTW, what is it
that you're trying to accomplish?

V
 
C

cbull

Victor Bazarov said:
No, it won't work. B::f is not a member of A. Pretending that it is will
not help solving whatever problem you're trying to solve. BTW, what is it
that you're trying to accomplish?

But I'm sure that I will always call it on correct object. And that is my
question. Will it always work while calling on object that this method
belongs to?
It's a part of slot - signal system.

Tomasz
 
V

Victor Bazarov

cbull said:
[..] Will it always work while calling on object that this method
belongs to?
It's a part of slot - signal system.

Actually, I am not sure. You'd need to dig into pointer adjustments
made to the member pointer when accessing (calling) a member of the base
for the object of the derived. Generally speaking, a pointer to member
function probably doesn't change when you cast it (or even when you
convert it properly). However, internally it may end up accessing the
wrong portion of the derived object.

V
 
H

Heinz Ozwirk

cbull said:
class A
{
};
class B: public A
{
void f();
};

typedef void (A::*MPA)(void);
MPA mpA;

B b;
mpA = (MPA) &B::f;

b->*mpA();


Will it work? If not then when it will fail? I've heard something about
multi inheritance.

First I thought, such things cannot work, but after reading some pages of
the standard I have my doubts

4.11 (Standard Conversions) says "An rvalue of type "pointer to member of B
of type cv T," where B is a class type, can be converted to an rvalue of
type "pointer to member of D of type cv T," where D is a derived class
(clause 10) of B."

Later 5.2.9 (static_cast) says "An rvalue of type "pointer to member of D of
type cv1 T" can be converted to an rvalue of type "pointer to member of B of
type cv2 T", where B is a base class (clause 10) of D, if a valid standard
conversion from "pointer to member of B of type T" to "pointer to member of
D of type T" exists (4.11), and cv2 is the same cv-qualification as, or
greater cv-qualification than, cv1"

Putting those pieces together I come to the conclusion that it should work,
if I correctly understand those parts of the standards and didn't miss other
important parts (for this problem). According to 4.11 there is a standard
conversion from void(A::*)() [aka MPA] to void(B::*)(), and, according to
5.2.9, if there is such a conversion, you can explicitly cast from void
(B::*)() to void (A::*)() using a static_cast.

HTH
Heinz
 
V

Victor Bazarov

Heinz said:
class A
{
};
class B: public A
{
void f();
};

typedef void (A::*MPA)(void);
MPA mpA;

B b;
mpA = (MPA) &B::f;

b->*mpA();


Will it work? If not then when it will fail? I've heard something about
multi inheritance.

[...] I come to the conclusion that it should work,
if I correctly understand those parts of the standards and didn't miss other
important parts (for this problem). According to 4.11 there is a standard
conversion from void(A::*)() [aka MPA] to void(B::*)(), and, according to
5.2.9, if there is such a conversion, you can explicitly cast from void
(B::*)() to void (A::*)() using a static_cast.

One thing is to convert pointers to members that way. Using them seems to
me a whole different matter.

V
 
C

cbull

cbull said:
class A
{
};
class B: public A
{
void f();
};

typedef void (A::*MPA)(void);
MPA mpA;

B b;
mpA = (MPA) &B::f;

b->*mpA();


Will it work? If not then when it will fail? I've heard something about
multi inheritance.

Tomasz

I've tried this construction under VC++ 2005 and it seems to work. Later I
will try it under gcc.

Tomasz
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,431
Messages
2,571,678
Members
48,796
Latest member
Greg L.

Latest Threads

Top