virtual inheritance from base struct

c++, struct, structure, virtual-inheritance

Solution

Without virtual When inheriting without `virtual`, you can imagine the memory structure to be like this:

class B : A {};

The variables of `A` are "inside" (just above) the variables of class `B`.

With virtual When inheriting with `virtual`, `B` just has a "pointer" to `A`:

class B : virtual A {};

Your example This means, your example looks like this:

class B : A
class C : B, virtual A

Only one instance of `A` If you only want one instance of `A`, you have to use `virtual` two times:

class B : virtual A
class C : B, virtual A

vptr's

Here is the layout of your code as it was produced by g++ (generated with `-fdump-class-hierarchy`):

Class C
   size=16 align=4
   base size=8 base align=4
C (0xb7193440) 0
    vptridx=0u vptr=((& C::_ZTV1C) + 12u)
  B (0xb719f078) 0
      primary-for C (0xb7193440)
    A (0xb719a428) 0
        primary-for B (0xb719f078)
  A (0xb719a460) 8 virtual
      vptridx=4u vbaseoffset=-12 vptr=((& C::_ZTV1C) + 28u)

I'm a bit rusty what concerns vpointers and vtables, so I'm not sure why there are exactly those v-pointers.

However, I can tell you, that your assumption that there is only one virtual method is wrong. Because `B` inherits from `A` and `A::f()` is virtual, the derived `B::f()` is automatically also virtual, even if you don't explicitly write this down.

edit:

After digging a bit, I think I remember which v-pointers are needed and which are not. However I won't give you any guarantee about the following. In the following, the notation `C.B.A` means the `A`-subobject in `B`, which is in `C`, to distinguish the both `A`-subobject (`C.B.A` and `C.A`).

Each subclass needs a v-pointer. However `*(C.B.A)`, `*(C.B)` and `*C` all point to the same location (namely the beginning of the class `C` which is also the beginning of `C.B` and `C.B.A`, therefore they can share one v-pointer. However a pointer to the subclass `*(C.A)` will point to a different location, therefore another vpointer is needed there. Also note that the subclass `C.B.A` won't even be accessible in your example (gcc: "warning: direct base ‘A’ inaccessible in ‘C’ due to ambiguity").

To make it a bit clearer: If you only had the following structure

class B : A {};
class C : B {};

only one vpointer would be needed as all pointers to any subclass of `C` would point to the same location. The vpointer would only have to point to the vtable of either `A`, `B` or `C` to tell which is the run-time type of the object.

Problem

``` struct A { int i; virtual void f() { cout << i; } A() { i = 1; } A(int _i) : i(_i) {} }; struct B : A { B() : A(2) { f(); } void f() { cout << i+10; } }; struct C : B, virtual A { C() : A() {} }; ``` Can you please explain why in the C structure there will be two A::i and why there will be two vptr pointers to 'virtual tables methods' for C structure although A only has virtual method ? I know when there is virtual inheritance from a common base there will be one instance of the common base not two ,Please advise!

Original source