I executed the following code.
#include <iostream>
class Base
{
public:
virtual void func()
{
std::cout<<"Base func called"<<std::endl;
}
};
class Derived: public Base
{
public:
virtual void func() override
{
std::cout<<"Derived func called"<<std::endl;
}
};
int main()
{
void (Base::*func_ptr)()=&Base::func; //Yes, the syntax is very beautiful.
Base* bptr=new Derived();
(bptr->*func_ptr)();
}
My expected output was Base func called
. However, Instead, the output was
Derived func called
Which surprised me, because I think that func_ptr
should be able to see only Base
members(because I thought that func_ptr
doesn't access the member function via _vptr
, but the function address itself.
I would like to know, how the virtual dispatch takes place in this case(how the access to virtual table takes place), and where this behavior is defined in C++ standard(I couldn't find anything)?
Refer to [expr.call], specifically here
[If the selected function is virtual], its final overrider in the dynamic type of the object expression is called; such a call is referred to as a virtual function call
Whether you call the function through a pointer or by class member access is the same (ref); the actual function called for a virtual function ultimately depends on the actual type of the object it is being called on.
A few (non-normative) notes in the standard under [class.virtual] say much the same thing:
[Note 3: The interpretation of the call of a virtual function depends on the type of the object for which it is called (the dynamic type)
[Note 4: [...] a virtual function call relies on a specific object for determining which function to invoke.
If you would like to know how the virtual function dispatch takes place, you will need to seek out a specific implementation, because the how is not standardized.
(I really enjoyed the article A basic glance at the virtual table, which shows one possible way you could implement it using C)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With