#include
using namespace std;
class base1{};
class base2{virtual void show(){}};
class test1{ };
class test2{virtual void show(){}};
class der
how to determine the size of virtual base class and derived classes from it??
Use sizeof()
.
An Empty class inheriting a base class in virtual (access specifier ) mode (ex.virtual public) has size of 8 while if is non-empty it would have a size of 16.
My old paper "C++: Under the Hood" explains the Microsoft C++ implementation of virtual base classes. http://www.openrce.org/articles/files/jangrayhood.pdf
And you can compile with cl /d1reportAllClassLayout to get a text report of class memory layouts.
Happy hacking!
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.