Can someone please explain about the size of the classes in the case of virtual inheritance involving virtual functions.
class A{
char k[ 3 ];
public:
virtual void a(){};
};
class B : public A{
char j[ 3 ];
public:
virtual void b(){};
};
class C : public virtual A{
char i[ 3 ];
public:
virtual void c(){};
};
class D : public B, public C{
char h[ 3 ];
public:
virtual void d(){};
};
The output of the size of the classes is :
sizeof(A): 8
sizeof(B): 12
sizeof(C): 16
sizeof(D): 32
The compiler I am using is
gcc version 4.6.1 (Ubuntu/Linaro 4.6.1-9ubuntu3)
3 bytes in the array, 1 byte padding, 4 bytes for the vptr (pointer to the vtable)
A subobject: 8, 3 bytes for the extra array, 1 byte padding
This is probably the surprising one for you…
A subobject: 8, 3 bytes for the extra array, 1 byte padding, 4 bytes pointer to A
Whenever you have virtual inheritance, the location of the virtual base subobject with respect to the start of the complete type is unknown, so an extra pointer is added to the original object to track where the virtual base is. Consider this example:
The location of
Awith respect to the start of theBobject when the complete type is aBcan be different than the location of theAsubobject ofBwhen it is part of the final objectD. If this is not obvious, assume that the relative location is the same, and check whether the relative location ofAwith respect toCin aCfinal object or aCsubobject inDcan also be maintained.As for the last example, I don’t quite feel like analyzing it… but you can read the Itanium C++ ABI for a concrete implementation of the C++ object model. All other implementations don’t differ much.
Last example:
D contains a B subobject (12), and a C subobject (16), plus an additional array of size 3 and one extra bit of padding 1.
In this particular case, the question that could come up is why are there two
Asubobjects ifCinherits virtually fromA, and the answer is that virtual base means that the object is willing to share this base with any other type in the hierarchy that is also willing to share it. But in this caseBis not willing to share it’sAsubobject, soCneeds it’s own.You should be able to track this by adding logs to the constructors at the different levels. In the case of
Ahave it take a value in the compiler and pass different values from each extending class.