Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Casting a pointer to virtual member function from derived class tobase class

Reply
Thread Tools

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

 
 
Alex Shen
Guest
Posts: n/a
 
      10-16-2010
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
 
Reply With Quote
 
 
 
 
Juha Nieminen
Guest
Posts: n/a
 
      10-16-2010
Alex Shen <(E-Mail Removed)> wrote:
> 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.
 
Reply With Quote
 
 
 
 
Alex Shen
Guest
Posts: n/a
 
      10-23-2010
2010/10/16 16:22, Juha Nieminen д:
> Alex Shen<(E-Mail Removed)> wrote:
>> 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.

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
 
Reply With Quote
 
Juha Nieminen
Guest
Posts: n/a
 
      10-23-2010
Alex Shen <(E-Mail Removed)> wrote:
> 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?
 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      10-25-2010
On Oct 16, 6:30 am, Alex Shen <(E-Mail Removed)> wrote:
> 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.)

--
James Kanze
 
Reply With Quote
 
Alex Shen
Guest
Posts: n/a
 
      10-30-2010
于 2010/10/25 18:29, James Kanze 写道:
> On Oct 16, 6:30 am, Alex Shen<(E-Mail Removed)> wrote:
>> 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.


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

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
forward declaration & virtual member function return derived class kepeng@gmail.com C++ 6 07-03-2008 08:04 PM
Derived::Derived(const Base&) and Derived& operator=(const Base&) developereo@hotmail.com C++ 1 05-23-2007 01:44 PM
Derived::Derived(const Base&) and Derived& operator=(const Base&) developereo@hotmail.com C++ 1 05-23-2007 12:07 AM
Pointer-to-member-function pointing to a member function of an inherited class akiriwas@gmail.com C++ 12 02-11-2005 05:15 PM
pointer to member function and pointer to constant member function Fraser Ross C++ 4 08-14-2004 06:00 PM



Advertisments