Fihop
Fihop

Reputation: 3177

converting pointer to base object into pointer of derivate class

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:

  • I'm a virtual function in base.
  • I'm a function in derivate class.
  • 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; 
    }
    

    Upvotes: 1

    Views: 277

    Answers (2)

    Foggzie
    Foggzie

    Reputation: 9821

    d1 is a derivate_class pointer but the data it's actually pointing to (cb) is of type base. Since print() is virtual, the call is resolved dynamically and so it will find base's implementation in the virtual function table instead of derivate_class's.

    Upvotes: 0

    Luchian Grigore
    Luchian Grigore

    Reputation: 258598

    It's UB, so anything can happen.

    But here's an explanation: d1 doesn't actually point to a derivate_class, but to a base.

    base* b = new base();
    //...
    base* cb = b;
    derivate_class *d1 = (derivate_class*)cb;
    d1->print();
    d1->print1();
    

    The call is resolved dynamically because it's through a pointer and the method is virtual.

    print1 isn't virtual so the call is resolved statically. print however is virtual, so the implementation in the most derived type is called. But the most derived type is actually base in this case.

    Under the hood, the method print is looked for in the virtual function table that the vfptr in cb points to. Since cv is a base, the table will be that of base, which contains the function print with the base::print implementation. That's why that's the function getting called.

    Upvotes: 3

    Related Questions