Writing code for a destructor in a side derived class in the case of multiple inheritance with polymorphism that increases the size of the Derived class. What for?

#include <iostream> struct Base1 { public: virtual void show()=0; }; struct Base2 { public: virtual void Display()=0; }; class Derived:virtual public Base1,virtual public Base2 { public: virtual void show(){} virtual void Display(){} }; void main() { using namespace std; cout<<sizeof(Derived); } 

12 is output, but when I insert the destructor of the Dervied class, that is, the following code

 #include <iostream> struct Base1 { public: virtual void show()=0; }; struct Base2 { public: virtual void Display()=0; }; class Derived:virtual public Base1,virtual public Base2 { public: virtual void show(){} virtual void Display(){} ~Derived(){} }; void main() { using namespace std; cout<<sizeof(Derived); } 

then it displays 20 as an output. why?

+4
source share
2 answers

1) Your base classes do not have a virtual destructor.
2) main return int, not void

What you ask is implementation. Using g ++ 4.3.0, I got the same size in both cases (8 bytes should be a good result on a 32-bit PC).

EDIT

According to a specific implementation, I meant that it depends on how virtual inheritance is implemented. Typically, a derived class contains pointers to base classes, but this is not necessary.

In the case of g ++, in order to be able to get the address of each sub-object (pointer to the base class), the size of Derived must be 12 bytes (on a 32-bit machine), but since all classes (i.e. without member variables), the compiler can freely optimize the size of empty base classes and reduce the size to 8 bytes (not 4 bytes, since it should be able to provide a different address for both base classes).

+1
source

Well, looking at the generated code, the first example has this memory layout:

 | Derived::vtable | Base1::vtable | Base2::vtable | 

The second has this layout:

 | Derived::vtable | 00 00 00 00 | Base1::vtable | 00 00 00 00 | | Base2::vtable | 

What zeros I do not know. They do not fill out, since the filling remains uninitialized with the help of CCCCCCCC . Perhaps they are used as counters or flags when deleting virtual subobjects, and when you add a destructor, these fields are added to the class. I was unable to distinguish them from 00000000 .

In any case, you can add this to your question: why, when I create a virtual destructor, then the layout becomes

 | Derived::vtable | 00 00 00 00 | Base1::vtable | 00 00 00 00 | | Base2::vtable | padding | 

(24 bytes)?

0
source

All Articles