10

I understand the concept of virtual inheritance, but I couldn't find the answer to this anywhere. Say you have class D which inherits class B and C. Both B and C inherit class A. So you could make B and C virtually inherit A to avoid two instances of A. But do you have to specify virtual inheritance at both B and C or does it already create only one instance of A if one of the two virtually inherits A and the other doesn't?

Thanks

Invalid
  • 1,870
  • 1
  • 16
  • 22

2 Answers2

14

They must all be virtual. From C++11 10.1 [class.mi]/7:

A class can have both virtual and non-virtual base classes of a given type.

class B { /* ... */ };
class X : virtual public B { /* ... */ };
class Y : virtual public B { /* ... */ };
class Z : public B { /* ... */ };
class AA : public X, public Y, public Z { /* ... */ };

For an object of class AA, all virtual occurrences of base class B in the class lattice of AA correspond to a single B subobject within the object of type AA, and every other occurrence of a (non-virtual) base class B in the class lattice of AA corresponds one-to-one with a distinct B subobject within the object of type AA. Given the class AA defined above, class AA has two subobjects of class B: Z’s B and the virtual B shared by X and Y, as shown below.

virtual inheritance example

Billy ONeal
  • 104,103
  • 58
  • 317
  • 552
  • Also, §10.1/4 actually defines this. – Joseph Mansfield Dec 06 '12 at 21:07
  • @sftrabbit: In what copy of the standard? In C++03, it is `10.1 [class.mi]/6`; in the latest available working paper, N3485, it is still `10.1 [class.mi]/7`. I don't have any standard copies where it is defined in `10.1 [class.mi]/4`. – Billy ONeal Dec 06 '12 at 21:10
  • I've always wondered why they didn't allow what OP is asking though. I don't see any logical obstacle to the virtual child pointing to the parent of the non-virtual child. – enobayram Dec 06 '12 at 21:14
  • @BillyONeal Apologies. What I meant is that 10.1/4 (in C++11) defines how many copies of the base class appear in the derived class, whereas your paragraph is an example of it occurring. :) – Joseph Mansfield Dec 06 '12 at 21:14
  • 2
    @enobayram: Because class `Z` in the above example may have invariants that assume that it has its own copy of class `B`. If a class is designed for virtual inheritance, its code must reflect that other classes may change its underlying copy of any virtually inherited members. – Billy ONeal Dec 06 '12 at 21:15
  • @BillyONeal Ah, good point, thanks. Though unless class `Z` is inheriting privately, it's already putting its invariants in similar danger. – enobayram Dec 06 '12 at 21:20
  • @enobayram: Maybe, maybe not. Depends on what class `B`'s member functions do :) – Billy ONeal Dec 06 '12 at 21:31
  • I see, thanks for a thorough explanation! Also, I'm wondering, if B only inherits A, and A inherits some other class virtually, could this cause a performance penalty? As in, would it be faster to not virtually inherit at A? – Invalid Dec 06 '12 at 21:36
  • @Invalid: Virtual inheritance always has a perf penalty. – Billy ONeal Dec 06 '12 at 22:24
9

You need to specify virtual inheritance for both B and C to have one A. Otherwise the class that is not using virtual inheritance will "share" class A.

This can enable one to have the following:

inheritance

Why you want to do this is another matter.

Ed Heal
  • 59,252
  • 17
  • 87
  • 127