Re: sizeof most-derived-class
On Apr 7, 7:25 pm, tonydee <tony_in_da...@yahoo.co.uk> wrote:
On Apr 8, 3:04 am, munna <saggitarius.a...@gmail.com> wrote:
Considering the classic diamond problem in where we have this
relationship,
=
A
/ \
B C
\ /
D
and define our classes like the following:
class A{
public:
virtual void f1(){}};
class B: public virtual A{
public:
void f1(){}};
class C: public virtual A{
public:
void f1(){}};
class D: public B, public C{
public:
void f1(){}
};
Specifically how the memory-layout for class D-object would be laid
out (in practice). Or is it so that since the standard doesn't
mandates any specific layout, compilers are free to have it at their
discretion? What i understand is that size of class A would be 4 bytes
(on a 32-bit architecture), sizeof B and C would be 8 bytes (one vptr
for B/C and one pointer to virtual base class A). How exactly would a
D object look like?
As Victor says, this isn't specified in the Standard, but typically a
compiler will want D to be a concatenation of a B and C object, as it
needs to be able to pass a pointer-to-(some-part-of)-D to functions
accepting B* or C*, and such functions aren't going to want to perform
some run-time check to see if parts of the B or C object are laid out
in a different layout used by some derived classes. So, expect sizeof
D to be sizeof B + sizeof C.
Virtual inheritance is involved. I would specifically expect not that.
For MSVC 2008 on a 32 bit build, I happened to get
sizeof A == 4
sizeof B == 8
sizeof C == 8
sizeof D == 12
WHAT FOLLOWS IS NOT PORTABLE. DO NOT RELY ON IT IN PRODUCTION CODE.
All D objects need to contain a B subobject, a C subobject, and
exactly one A subobject. As such, it cannot simply put A's members at
offset 0 in the B subobject and offset 0 in the C suboject. (Think
about it.) Normally, to convert between a base class pointer and a
derived class pointer, just a compile time known offset is added (0
for single inheritance, and zero and nonzero for multiple
inheritance). For virtual inheritance, the offset to a base class
subobject is no longer a compile time constant, and it must be looked
up at runtime, hence this extra "stuff" in the B, C, and D objects.