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:
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. For some reason it is not showing up in the debugger.
Cheers.
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 :
_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 classBut 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 ofderivedClass
correspond to the vtable ofbaseClass
. 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 functionderivedClassOnlyVirtualFunc
but is not shown by debugger as I said above.