Casting a pointer to virtual member function from derived class tobase class

A

Alex Shen

Hi all, pls consider the following code,

#include <iostream>

struct base
{
virtual void f()
{
std::cout << "base::f\n";
}
};

struct derived : base
{
virtual void f()
{
std::cout << "derived::f\n";
}
};

int main()
{
typedef void (base::* base_ptr_type)();
typedef void (derived::* derived_ptr_type)();

derived_ptr_type pd(&derived::f);
base_ptr_type pb(reinterpret_cast<base_ptr_type>(pd));

derived d;
(static_cast<base*>(&d)->*pb)(); // output "derived::f"
}

IIRC, MFC uses this technique in it's message mapping implmentation.
It's not portable, right? Because of the use of reinterpret_cast whose
result is undefined as the standard says.

Alex
 
J

Juha Nieminen

Alex Shen said:
typedef void (base::* base_ptr_type)();
typedef void (derived::* derived_ptr_type)();

derived_ptr_type pd(&derived::f);
base_ptr_type pb(reinterpret_cast<base_ptr_type>(pd));

I don't know what the standard says about that, but I would be very
surprised if it's not huge Undefined Behavior (especially since a
virtual member function pointer is more complex than a regular function
pointer).

Also, I don't understand the need. You can have a pointer to a virtual
function of the base class, and then use it to call the function for an
object, and the dynamic binding will work (in other words, if the object
is really of a derived type and that derived type implements the virtual
function, the derived version will be called). There's no need for such
hazardous casting.
 
A

Alex Shen

ÓÚ 2010/10/16 16:22, Juha Nieminen дµÀ:
I don't know what the standard says about that, but I would be very
surprised if it's not huge Undefined Behavior (especially since a
virtual member function pointer is more complex than a regular function
pointer).

Also, I don't understand the need. You can have a pointer to a virtual
function of the base class, and then use it to call the function for an
object, and the dynamic binding will work (in other words, if the object
is really of a derived type and that derived type implements the virtual
function, the derived version will be called). There's no need for such
hazardous casting.
Assume that I need to call a virtual function from the base class
according to a runtime condition. By storing all pointers to virtual
functions in a container, I can avoid the if-else statement to
dertermine which virtual function to be called in the base class. I
agree with you that this horrible casting should be avoided and function
object such as boost::function can be used to store member function
pointers.I'm just curious about such code.

Alex
 
J

Juha Nieminen

Alex Shen said:
Assume that I need to call a virtual function from the base class
according to a runtime condition. By storing all pointers to virtual
functions in a container, I can avoid the if-else statement to
dertermine which virtual function to be called in the base class.

I still don't understand what the problem is. If you want to store
member function pointers into a container, then store them. As said,
if such a member function is virtual, calling it through the pointer
will work ok (ie. the possible dynamic binding will be taken into account
when calling the function, even if you do it through a base class member
function pointer). What is the problem you are having?
 
J

James Kanze

Hi all, pls consider the following code,
#include <iostream>
struct base
{
virtual void f()
{
std::cout << "base::f\n";
}
};
struct derived : base
{
virtual void f()
{
std::cout << "derived::f\n";
}
};
int main()
{
typedef void (base::* base_ptr_type)();
typedef void (derived::* derived_ptr_type)();
derived_ptr_type pd(&derived::f);
base_ptr_type pb(reinterpret_cast<base_ptr_type>(pd));

This shouldn't require (or use) a reinterpret_cast.
A static_cast is sufficient.
derived d;
(static_cast<base*>(&d)->*pb)(); // output "derived::f"
}
IIRC, MFC uses this technique in it's message mapping
implmentation. It's not portable, right? Because of the use
of reinterpret_cast whose result is undefined as the standard
says.

Correct. Use a static_cast, and everything should be OK. (And
Microsoft isn't the first to use this technique.)
 
A

Alex Shen

于 2010/10/25 18:29, James Kanze 写é“:
This shouldn't require (or use) a reinterpret_cast.
A static_cast is sufficient.

Now, I believe that this technique is valid because we can use
static_cast instead of the horrible reinterpret_cast. I just found
paragraph 5.2.9/9 in C++03 draft which specifies this kind of casting.

Alex
 

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
473,755
Messages
2,569,536
Members
45,013
Latest member
KatriceSwa

Latest Threads

Top