It will be extremely platform dependent, but I think we can understand what is happening.
Firstly, the standard does not specify how virtual inaction should be implemented. As for the standard, there is not even such a thing as vtable.
ABCDerived has BBase and CBase Each of which consists of int . There is also one instance of ABase that consists of an int . Finally, there is vtable ptr.
The size of an int is platform dependent - this is not necessarily 4 bytes. But if we assume that it is 4 bytes, and the size of vtable is also 4 bytes, we have:
int [ABCDerived] = 4 bytes int [CBase] = 4 bytes int [BBase] = 4 bytes int [ABase] = 4 bytes vtable = 4 bytes ------------- 20 bytes
This does not mean that sizeof (ABCDerived) is 20. Equalization also plays here. The standard allows compilers to increase the size of an object so that the size is divided into several whole words.
Consider:
class ABase{ int iMem; }; class BBase : public virtual ABase { int iMem; }; class CBase : public virtual ABase { int iMem; }; class ABCDerived : public BBase, public CBase { int iMem; }; int main() { ABCDerived d; BBase& b = d; ABase* ab = &b; CBase& c = d; ABase* ac = &b; cout << hex << (void*) ab << "\n" << hex << (void*) ac << "\n"; cout << sizeof (d) << "\n" << sizeof (int) << "\n"; }
Pin 28 on my 64-bit Linux machine.
However, if I turn on the packaging (using the platform-specific #pragma switch):
#pragma pack (1)
Now 20 is displayed.
So long and short of all of this:
There is a ton of platform-dependent stuff. You cannot say that the size of an object is one or the other, at least without using more platform-dependent materials and knowing how your compiler actually implements virtual inheritance. Its size depends on its size.
source share