开发者

Writing code for destructor in side derived class in case of multiple inheritance with polymorphism increasing size of Derived class. Why?

#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);
}

output is showing 12 but when i insert destructor of Dervied class i.e. following code

#in开发者_如何学运维clude <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 is showing 20 as output. why?


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

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

EDIT

Under implementation defined, I meant it depends on how the virtual inheritance is implemented. Usually, the derived class contains pointers to base classes, but that't not necessary the case.

In the case of g++, to be able to get the address of every sub-object (pointer to a base class), the size of Derived should be 12 bytes (on a 32-bit machine), but because all classes are empty (i.e. without member variables), the compiler is free to optimize the size of empty base classes, and to reduce the size to 8 bytes (not 4 bytes, because it needs to be able to provide different address of both base classes).


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 are the zeros I don't know. They are not padding, since padding is left uninitialized with CCCCCCCC. Maybe they are used as counters or flags when deleting the virtual subobjects and when you add the destructor these fields are added to the class. I failed in making them different from 00000000.

Anyway, you can add this to your question: Why when I make the destructor virtual then the layout becomes

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

(24 bytes)?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜