How to determine the size of a virtual base class and derived classes?

#include <iostream> using namespace std; class base1{}; class base2{virtual void show(){}}; class test1{ }; class test2{virtual void show(){}}; class derv1:public virtual base1{}; class derv12:public virtual base2{}; class derv2:public virtual base2, public test1{}; class derv22:public virtual base2, public virtual test1{}; class derv222:public virtual base2, public virtual test2{}; int main() { cout<<"sizeof base1 = "<<sizeof(base1)<<endl; cout<<"sizeof base2 = "<<sizeof(base2)<<endl; cout<<"sizeof derv1 = "<<sizeof(derv1)<<endl; cout<<"sizeof derv12 = "<<sizeof(derv12)<<endl; cout<<"sizeof derv2 = "<<sizeof(derv2)<<endl; cout<<"sizeof derv22 = "<<sizeof(derv22)<<endl; cout<<"sizeof derv222 = "<<sizeof(derv222)<<endl; } 

outputs:

 sizeof base1 = 1 sizeof base2 = 4 sizeof derv1 = 4 sizeof derv12 = 8 sizeof derv2 = 8 sizeof derv22 = 8 sizeof derv222 = 12 

I understand the following outputs:

 sizeof base1 : 1 => empty class , size is 1. result is OK. sizeof base2 : 4 => since class has a virtual function, it adds a vitual pointer in each object of the class ( 32 bit machine) , so added 4 bytes. Result is OK. sizeof derv1 : 4 => base1 doesn't have virtual function but since derv1 is virtually derived from base1 ,added 4 bytes. I think that each virtual base class added a pointer in object so i think Result is OK. sizeof derv12: 8 => 4 bytes( from virtual pointer) + 4 bytes (virtual base class ) = 8 bytes. Result is OK. 

My confusion begins after exits

 sizeof derv2 : 8 => 8 bytes( virtual pointer + virtually base class) from base2 + 1 byte from test1 => 9 bytes and adds 3 padding bytes gives 12 bytes (should print). why "sizeof (test1)" is not adding in the output ?? sizeof derv22 : 8 => 8 bytes( virtual pointer + virtually base class) from base2 + 4 byte (virtually base class) from test1 => 12 bytes (should print) why 4 bytes from test1 (virtual base class) is not added in the output?? In the size of(derv1 ) also has a virtual base class( base1) and out put is 4 bytes means they added 4 bytes in the output. sizeof derv222: 12 => 12 bytes( virtual pointer + virtually derived) from base2 + 8 byte( virtual pointer + virtually derived) from test2 => 16 bytes (should print) 

Am I missing somethineg or are these sizes system dependent or something else?

+6
source share
4 answers

The reason that sizeof(base1) and sizeof(test1) is 1 is solely to prevent the derivative of size 0 from being received. That all standards prohibit. Sub-objects of the base class are allowed to have size 0 (i.e., they are allowed not to occupy bytes), and therefore, adding base1 as the base does not have to add anything to the size of the class.

The optimization done by your compiler, and not the allocation of bytes for a sub-object of a base class whose type is an empty class, is called "empty base class optimization". The standard does not require the implementation to apply it, but an implementation that could not be considered suitable for serious work.

I think derv22 somewhat similar - if the compiler is able to deal with two virtual base classes using one additional pointer, then it has the right to do so. Therefore, you may only need to “pay” once, rather than “pay” for the virtual database. This may depend on the compiler and on the exact relationships between the classes, although I never looked at various implementations to see if and when they are forced to add a few pointers to overhead.

derv222 apparently did this, though, at least for your compiler. I believe this is because sub-objects of the base class base2 and test2 need separate vtable pointers. Probably not surprising if you think what happens when you static_cast a derv222* as a pointer to one database or the other - both results should be able to call show() on them and call various functions (although show functions are currently nothing do not do). I'm not sure if another compiler can implement this inheritance in 8 bytes - for one thing, inheritance should not be implemented using vtables.

+10
source

How to determine the size of a virtual base class and derived classes from this ??

Use sizeof() .

+5
source

My old article "C ++: Under the Hood" explains the implementation of Microsoft's virtual C ++ base classes. http://www.openrce.org/articles/files/jangrayhood.pdf

And you can compile with cl / d1reportAllClassLayout to get a text report on class memory layouts.

Happy hack!

+3
source

An empty class that inherits the base class in virtual mode (access specifier) ​​(ex.virtual public) has a size of 8, and if it is not empty, it will have a size of 16.

0
source

All Articles