How a single vtable is tracking new virtual functions?

311 views Asked by At

I'm using VS 2013 and trying to see how vptr and vftable are working at object level. So I have the following classes:

#include<iostream>
using namespace std;

class baseClass
{
public:
    void nonVirtualFunc() {}
    virtual void virtualNonOverriddenFunc() {}
    virtual void virtualOverriddenFunc() {}
};

class derivedClass : public baseClass
{
public:
    virtual void virtualOverriddenFunc() {}
    virtual void derivedClassOnlyVirtualFunc() { cout << "derivedClass" << endl; }
};


int main(int argc, char** argv) {

    derivedClass derivedClassObj2;
    cout << "Size of derivedClassObj: " << sizeof(derivedClassObj2) << endl;

    return 0;
}

And this is what I see when debugging: enter image description here

Theoretically there should be TWO vptrs. One for the vftable of baseClass and one for derivedClass to track the newly added derivedClassOnlyVirtualFunc().

But as you see, there is only one vptr/vftable. But the mechanism works fine.

I thought there is second vptr that I cannot see in the watch window, so I printed out the size of the object. It is 4 bytes, indicating that only one pointer is present.

So how is this working with the newly added virtual function?

According to this there should be two vptrs.

EDIT: I checked the memory contents of vftable as Serge suggested and there indeed are three entries. enter image description here For some reason it is not showing up in the debugger.

Cheers.

1

There are 1 answers

3
Serge Ballesta On BEST ANSWER

The vtable implementation is compiler dependant. The size of the object (4 bytes) show that the vtable is not replicated in the object since 4 bytes is just one pointer. My understanding is :

  • there is one and only one vtable(*) per class (not per object)
  • each object has a pointer to its vtable (the one of its actual class)
  • as _vfptr is an attribute of the ancestor class, the debugger shows it under the ancestor class, and as such only shows the methods defined in that class

But for sure the real _vtable contains entry for the other virtual methods ... after the entries displayed by the debugger !

(*) Things become harder when you think about the internal organization of the _vfptr array. In fact, it can be seen as containing copies of all the vtables of ancestor classes. Here, the 2 first entries of derivedClass correspond to the vtable of baseClass. But if you open a Memory window, and examine what is at the _vfptr address (0x00d9ba68 in your example) you should see a third entry before a null entry (at least that is what my MSVC Express 2008 shows). This third entry correspond to the function derivedClassOnlyVirtualFunc but is not shown by debugger as I said above.