简体   繁体   中英

Confusion with virtual pointer of derived class

Base having a virtual function and Derived also having one virtual function like this,

class Base
{
    private:
        int i;
    public:
        Base(int data = 9):i(data)
        {
            cout << "In Base class constructor" << endl;
        }
        void display()
        {
            cout << "In Base class" << endl;
            cout << "i = " << i << endl;
        }
        virtual ~Base()
        {
            cout << "In Base class destructor" << endl;
        }
};

class Derived: public Base
{
    private:
        int j;
    public:
        Derived(int data = 10):Base(11),j(data)
        {
            cout << "In Derived class constructor" << endl;
        }
        virtual void display()
        {
            cout << "In Derived class" << endl;
            cout << "j = " << j << endl;
        }
        ~Derived()
        {
            cout << "In Derived class destructor" << endl;
        }
};

Now in gdb I see the total size of the Derived class object is 16 bytes (int+int+_vptr+_vptr), but when I print each object in gdb I'm getting confused, for base class it's showing like this

$1 = {_vptr.Base = 0x401010, i = 11} and it's fine, but for derived it's showing something like this

$2 = {<Base> = {_vptr.Base = 0x401010, i = 11}, j = 10}

I'm not seeing the virtual pointer of the derived class. As per my understanding in addition to the base class virtual pointer which is inherited, there should be one more virtual pointer in the derived class that should point to it's own virtual table. Am I doing something wrong here or is there any other way to get it?

The derived class has its own vtable . So objects of that type have a single pointer to it. That vtable contains entries that point to Base s member functions if they aren't overridden. So there is no need for a pointer to Base s vtable in objects of type Derived .

The reason _vptr.Base appears in Derived is because you didn't override any functions. The compiler doesn't generate a vtable for Drived because it will just be a duplicate of Base s.

With single inheritance, there is typically just one virtual function pointer: it points to something like an array of function pointers. The number of entries contributed by the base class is known and the derived class just tags its own virtual functions to the end.

Of course, how the virtual function table actually works exactly depends on the respective ABI. You can have have a look, eg, at the Itanium C++ ABI which is used on Linuxes and possibly on other systems.

The derived class doesn't have a separate, additional pointer to its vtable - rather, the vtable pointer inherited from the base class will be overwritten to point to the derived class's vtable as the derived class's constructor runs (and later reverted as the destructor runs).

That way, when operations are done on a Base* or Base& to the Base member embedded in a constructed derived object, the pointer to the VDT seen (at the usual offset into the Base object) allows dispatched to the derived class's methods.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM