Pergunta

The size of of the classes as follow while using virtual inheritance..

ABase=4(sizeof imem)
BBase=12(sizeof imem+ABase+VBase_ptr)
CBase=12(sizeof imem+ABase+VBase_ptr) 

This is justified, but i do not understand why the size of ABCDerived is 24.

class ABase{ 
        int iMem; 
}; 

class BBase : public virtual ABase { 
        int iMem; 
}; 

class CBase : public virtual ABase { 
        int iMem; 
}; 

class ABCDerived : public BBase, public CBase { 
        int iMem; 
}; 
Foi útil?

Solução

This is going to be extremely platform-dependant, but I think we can understand what's going on.

First off, the Standard doesn't specify how virtual inheitence is to be implemented. As far as the Standard is concerned, there's not even any such thing as a vtable.

ABCDerived has BBase and CBase Each of which is comprised of an int. There is also a single instance of ABase which is comprised of an int. Finally there is a vtable ptr.

The size of an int is platform dependant -- it's not necesarrily 4 bytes. But if we assume it is 4 bytes, and the size of the vtable is also 4 bytes, we have:

int  [ABCDerived] = 4 bytes
int  [CBase]      = 4 bytes
int  [BBase]      = 4 bytes
int  [ABase]      = 4 bytes
vtable            = 4 bytes
                 -------------
                   20 bytes

That doesn't mean the sizeof (ABCDerived) is 20 however. Alignment comes in to play here as well. The Standard allows compilers to increase the size of an object so that the size is divisible by a number of whole words.

Consider:

class ABase{ 
            int iMem; 
}; 

class BBase : public virtual ABase { 
            int iMem; 
}; 

class CBase : public virtual ABase { 
            int iMem; 
}; 

class ABCDerived : public BBase, public CBase { 
            int iMem; 
}; 

int main()
{
    ABCDerived d;
    BBase& b = d;
    ABase* ab = &b; 
    CBase& c = d;
    ABase* ac = &b; 

    cout << hex << (void*) ab << "\n"
        << hex << (void*) ac << "\n";

    cout << sizeof (d) << "\n" << sizeof (int) << "\n";
}

The output is 28 on my 64 bit Linux machine.

However if I turn on packing (using a platform-dependant #pragma switch):

#pragma pack (1)

The output is now 20.

So, the long and the short of all this is:

There is a ton of platform-dependant stuff going on here. You can't say the size of the object is this or that, at least without employing more platform-dependant stuff and knowing how your compiler actually implements virtual inheritence. The size of it is whatever the size of it is.

Outras dicas

Size should be 20, As you used virtual inheritance ABCDerived wont inherit ABase IMem twice. As you are telling it is giving 24, May be virtual inheritance is not supporting by your compiler.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top