I’ve been confused by the converting a pointer to base class object into pointer of derivate class.
Please check the following code:
derivate_class *d1 = (derivate_class*)cb;
d1->print();
d1->print1();
The result is:
Can anyone help me explain why d1->print() print “I’m a virtual function in base.”?
#include <iostream>
using namespace std;
class base
{
public:
virtual void print()
{
cout << "I'm a virtual function in base." << endl;
}
};
class derivate_class : public base
{
public:
void print()
{
cout << "I rewrite the virtual function in base." << endl;
}
void print1()
{
cout << "I'm a function in derivate class." << endl;
}
};
int main()
{
base* b = new base();
derivate_class *d = new derivate_class();
b->print();
d->print1();
base* cb = b;
b = d;
b->print();
cout << "*********************" << endl;
derivate_class *d1 = (derivate_class*)cb;
d1->print();
d1->print1();
system("pause");
return 0;
}
It’s UB, so anything can happen.
But here’s an explanation:
d1doesn’t actually point to aderivate_class, but to abase.The call is resolved dynamically because it’s through a pointer and the method is
virtual.print1isn’tvirtualso the call is resolved statically.printhowever isvirtual, so the implementation in the most derived type is called. But the most derived type is actuallybasein this case.Under the hood, the method
printis looked for in the virtual function table that the vfptr incbpoints to. Sincecvis abase, the table will be that ofbase, which contains the functionprintwith thebase::printimplementation. That’s why that’s the function getting called.