Islam Abdeen
Islam Abdeen

Reputation: 539

Size of most derived class in virtual inheritance

In below code why the size of D is 16 instead of 8 bytes?

I think because we have virtual base class so there should be only one instance of A.

class A
{
public:
    int x_;
    int y_;
};

class B :  virtual public A
{
};

class C :  virtual public A
{

};

class D :  public B, public C
{
};

Upvotes: 0

Views: 89

Answers (2)

eerorika
eerorika

Reputation: 238311

I think because we have virtual base class so there should be only one instance of A.

That is correct.

In below code why the size of D is 16 instead of 8 bytes?

On my system, D is 24 bytes.

D contains one B subobject (excluding A), one C subobject (excluding A), and one virtual A subobject.

Since the bases are not standard layout, empty base optimisation is not required and each base has a unique address and thus occupy memory despite having no subobjects themselves.

Furthermore (depending on how virtual bases are implemented by your compiler), the virtual inheritance necessitates the use of a virtual table to access the virtual base, so the instance will have a virtual pointer to that table.

Upvotes: 2

curiousguy
curiousguy

Reputation: 8270

In below code why the size of D is 16 instead of 8 bytes?

In any case, all these derived classes cannot (practically (*)) have the same size as their virtual base A:

  • the relation of derived class object to a non virtual direct base subobject is, like the relation with a member subobject, a one to one relation;
  • the relation of derived class object to a virtual base subobject is a many to one relation: by definition a specific virtual base subobject can be the direct base of more than one derived classes. Here the A base subobject is the direct base of both B and C subobjects of a D object (or subobject of yet another derived object).

(*) I know there are possible implementation methods that violate that assertion, but they are a lot less efficient, clumsy, and harder to make thread safe, and even less efficient in threaded programs.

Because the relation is many to one, the class layout cannot be fixed (unlike with a non virtual member or member). The location of the unique base subobject depends on the exact derived class created.

A (g)lvalue of a class X refers to an instance of type X or a class derived from X; so when using such (g)lvalue that doesn't refer to a known object (when using the name of locally declared object, the type by definition is known), the address of the base subobject is determined at runtime from type (or address) information embedded in the instance.

So B and C need to carry such information to locate the virtual base. That makes them larger than their base. The most derived class needs room for the location information in all non virtual bases, plus the virtual base itself (usually placed at the end if it has any data members).

Upvotes: 2

Related Questions