Virtual Inheritance
This is pretty cool. Introduced in CS247. I didn’t know this was a thing.
Virtual inheritance is a C++ technique that ensures only one copy of a base class’s member variables are inherited by grandchild derived classes.
Virtual Inheritance helps us fix the Diamond Problem.
Syntax
The keyword virtual
indicates that this base class will be shared among all others who inherit from it virtually in the inheritance hierarchy.
Now, dOjb.a
unambiguous, a
field is now shared between both patterns of the object.
Constructors for virtual bases must run before any other constructors.
- This shows the order in which the objects is constructed for virtual inheritance:
- Calls
D
’s constructor - Calls
A
’s constructor - Returns to
D
- Calls
B
’s constructor - Returns to
D
- Calls
C
’s constructor - returns to
D
Fixed
Object Layout with Virtual Inheritance
How does object layout work with multiple virtual inheritance?
B
object:
To treat a B*
like an A*
, simply create a pointer copy, points at the same location, ignore B
fields. Same strategy cannot be used for multiple virtual inheritance.
Note
virtual Base(A)
is actually stored at the end of the object! Not the beginning.
If bp
points at a D
object, see above memory diagram.
If bp
points at a B
object,
Note
- If we’re pointing at a
D
object,bp->a
is 40 bytes below the pointer address.- If we’re pointing at a
B
object,bp->a
is 24 bytes below the pointer address.
Note: Now, finding superclass fields depends on the dynamic type.
Solution: Store the offset to the superclass fields inside of the vtable.
This is where the new “virtual” inheritance comes from.
Note: The D
object does not look like an A
object, a C
object, or a D
object simultaneously, but portions of it do.
Doing pointer assignment can change where the pointer is pointing to.
- This is really IMPORTANT, be careful
static_cast
/dynamic_cast
will also adjust pointer locations for you as necessary.reinterpret_cast
won’t - underscores danger associated with the cast.
Finally, both Google C++ Style guide, and ISOCpp both recommend when using multiple inheritance, Interface Classes are best.