how to determine the size of virtual base class and derived classes from it?

The reason that sizeof(base1) and sizeof(test1) are 1 is solely to prevent a most-derived object from having size 0. That’s all the standard forbids. Base class sub-objects are allowed to have size 0 (that is, allowed to occupy no bytes), and hence adding base1 as a base doesn’t necessarily have to add anything to the size of the class.

The optimization your compiler has made, not allocating any bytes for a base-class sub-object whose type is an empty class, is called the “empty base class optimization”. It’s not required by the standard that the implementation apply it, but an implementation that didn’t might not be considered fit for serious work.

I think derv22 is somewhat similar – if the compiler is capable of dealing with two virtual base classes using a single extra pointer, then it’s entitled to do so. Hence, you might only have to “pay” once, rather then “paying” per virtual base. That could depend on the compiler and on the exact relationships between the classes, though, I’ve never surveyed different implementations to see if and when they’re forced to add multiple pointers worth of overhead.

Apparently derv222 has done it, though, at least for your compiler. I suppose that this is because the base2 and test2 base class sub-objects need separate vtable pointers. Probably not that surprising if you consider what happens when you static_cast a derv222* as a pointer to one base or the other – both results need to be capable of having show() called on them, and calling different functions (albeit the show functions currently do nothing). I’m not sure whether it would be possible for another compiler to implement this inheritance in 8 bytes — for one thing inheritance doesn’t have to be implemented using vtables.

Leave a Comment