Returning ptr to a virtual member function of a base class

D

Dave Rahardja

Consider the following example:

---

#include <iostream>

class Base
{
public:
virtual void fn() { std::cout << "Base::fn()\n"; }
};

typedef void (Base::*Base_fn_ptr)();

class Derived: public Base
{
public:
virtual void fn() { std::cout << "Derived::fn()\n"; }

static Base_fn_ptr Get_Base_Fn_Ptr() { return &Base::fn; }
};

int main()
{
Derived obj;
Base_fn_ptr ptr = Derived::Get_Base_Fn_Ptr();
(obj.*ptr)();

return 0;
}

---

Running the example causes "Derived::fn()" to be output. Is there a way
to craft Get_Base_Fn_Ptr() so that it returns the address of Base::fn()
instead of a virtual function-calling stub?

In other words, I want to defeat the polymorphic behavior of obj.

- Dave Rahardja
 
G

GianGuz

If I understand what you need, the way to defeat the polimorfic
behaviour of obj is to use the explicit qualification mechanism in
calling fn.

In your code you only have to call:

obj.Base::fn(); // explicit call to Base fn()
obj.Derived::fn(); // explicit call to Derived fn()

Gianguglielmo
 
J

Jonathan Mcdougall

Dave said:
Consider the following example:

---

#include <iostream>

class Base
{
public:
virtual void fn() { std::cout << "Base::fn()\n"; }
};

typedef void (Base::*Base_fn_ptr)();

class Derived: public Base
{
public:
virtual void fn() { std::cout << "Derived::fn()\n"; }

static Base_fn_ptr Get_Base_Fn_Ptr() { return &Base::fn; }
};

int main()
{
Derived obj;
Base_fn_ptr ptr = Derived::Get_Base_Fn_Ptr();
(obj.*ptr)();

return 0;
}

---

Running the example causes "Derived::fn()" to be output. Is there a way
to craft Get_Base_Fn_Ptr() so that it returns the address of Base::fn()
instead of a virtual function-calling stub?

In other words, I want to defeat the polymorphic behavior of obj.

By using pointer to member functions, no. This system was especially
made for these cases: to make sure wherever in the hierarchy you take an
address, the correct function gets called.

You are probably aware you can call it directly by qualifying the function :

obj->Base::fun();


However, look at that :

# include <iostream>

class Base
{
public:
void f()
{
std::cout << "in base::f()";
}

virtual void vf()
{
f();
}
};

class Derived : public Base
{
public:
virtual void vf()
{
std::cout << "in derived::vf()";
}
};


typedef void (Base::*Pf)();

Pf test1()
{
return &Base::f;
}

Pf test2()
{
return &Base::vf;
}

int main()
{
Base *b = new Derived;

Pf pf = test1();
(b->*pf)(); // in derived::vf()

pf = test2();
(b->*pf)(); // in base::vf()

}

This may or not be what you look for.


Jonathan
 
D

Dave Rahardja

GianGuz said:
If I understand what you need, the way to defeat the polimorfic
behaviour of obj is to use the explicit qualification mechanism in
calling fn.

In your code you only have to call:

obj.Base::fn(); // explicit call to Base fn()
obj.Derived::fn(); // explicit call to Derived fn()

Gianguglielmo

That's exactly what I'm looking for. Thanks! I guess the syntax of the
explicit call escaped me.

-dr
 

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,011
Latest member
AjaUqq1950

Latest Threads

Top