9

The following code are from the book "Inside the C++ object model"

#include <iostream>  
using namespace std;
class X{};
class Y: public virtual X{};
class Z: public virtual X{};
class A: public Y, public Z{};

int main()
{
     cout<<sizeof(X)<<" "<<sizeof(Y)<<" "<<sizeof(Z)<<" "<<sizeof(A)<<endl;
     return 0;
}

In my computer(Windows, VS2010), the output is:

1 4 4 8

Here're my questions

1, sizeof(X)=1

The book says when X type generate two instance, say xa and xb. the compile insert a byte into A so that xa and xb can have different address. I'm not quite understand the reasons.

2, sizeof(Y)=4

By using virtual inheritance, will we have an additional virtual pointer? I guess this might be different from virtual pointer in polymorphism. Can anyone give me the memory layout for Y?

Thank you!

nogard
  • 9,432
  • 6
  • 33
  • 53
Junjie
  • 469
  • 1
  • 4
  • 14
  • One question per question please – Lightness Races in Orbit Oct 31 '12 at 11:32
  • for the 1st question, check: http://stackoverflow.com/questions/621616/c-what-is-the-size-of-an-object-of-an-empty-class?rq=1 – mots_g Oct 31 '12 at 11:33
  • 1
    I think your main question is that because Y uses virtual inheritence to derive from a non-polymorphic class X, and Y itself is non-polymorphic, will the virutal inheritence itself cause Y to have a v-table thus its size being 4.. – CashCow Oct 31 '12 at 11:46

4 Answers4

6
  1. compiler new one char when the class is empty, so it can generate different object
  2. sizeof(Y)=4 because it's virtual inheritance, construct will generate vptr table which is 4 bytes on 32-bit system
  3. if you are using visual studio use /d1reportAllClassLayout in properties->C/C++/Command to generate object layout class Y object layout will be on Visual Studio:
  4. book 'Inside C++ object model' by Stanley B. Lippman explained this extremely well

 
        class Y size(4):
            +---
            0     | {vbptr}
            +---
            +--- (virtual base X)
            +---
Y::$vbtable@: 0 | 0 1 | 4 (Yd(Y+0)X) vbi: class offset o.vbptr o.vbte fVtorDisp X 4 0 4 0
billz
  • 44,644
  • 9
  • 83
  • 100
1

sizeof of an empty class always returns 1. Thats a single dummy byte for an empty class.

A holds the two entries in the virtual table, one for Y other for Z

So the sizeof two pointers i.e. 8.

Y and Z hold both have a single entry of X in their virtual table, hence the size is 4.

N3Xg3N
  • 97
  • 1
  • 12
1

An A object will include an Y object, a Z object (in that order) and only one X Object (referenced by pointers in Y and Z), because both Y and Z inherit virtually from X, thus meaning that when multiple inheritance comes to play only one X object will be instantiatet within the child-classes. A still has two objects (one Y, one Z) and thus has sizeof = 8 (since they both have sizeof = 4). But both pointers in Y and Z to the X object will point to the same address.

The inheritance tree will look like:

  X
 / \
 Y Z
 \ /
  A
hildensia
  • 1,650
  • 2
  • 12
  • 24
0

The reason classes -must- be at least 1 byte is say we have an array of X. If they were 0 bytes then &array[1] would have the same address as &array[3] which no one would expect, would break code, be annoying if you had to write code to check for that and typically won't make any sense.

Y would simply be

static void* virtual_ptr1 //note this is in virtual table and cannot be edited  

You can think of vtables (virtual pointers to classes and virtual functions) as static variables that you can not edit by hand/code (or at least should not). Think of it as compiler reserved static variables