ReviseAlgo Logo

Object-Oriented Programming

Multiple Inheritance

Inheriting from multiple base classes — power and pitfalls including the diamond problem

Interview: Diamond problem, virtual inheritance, and interface implementation — advanced OOP interview topic

Multiple Inheritance

Multiple inheritance allows a class to inherit from more than one base class: class C : public A, public B {}. C inherits all members of A and B. While powerful, it introduces significant complexity — particularly the diamond problem — and is used sparingly in well-designed C++ codebases.

The Diamond Problem

When two bases share a common ancestor (D → B, C; B → A; C → A), D ends up with two copies of A's members — ambiguity for all accesses. Virtual inheritance solves this: class B : virtual public A and class C : virtual public A — only one shared copy of A exists in the final object D.

Mixin Pattern

The most practical use of multiple inheritance in modern C++ is the mixin pattern: combining a concrete class with multiple pure-interface abstract classes. This closely mirrors Java's implements: class AudioPlayer : public Playable, public Serializable {}.

Constructor Order with Multiple Bases

Base classes are constructed in the order they appear in the inheritance list (left to right), then the derived constructor body runs. Virtual base classes are initialized first, before any non-virtual bases. Destructors run in reverse order.

Interview Corner

Q: What is the diamond problem and how does virtual inheritance solve it?

A: In diamond inheritance, a class D inherits from B and C which both inherit from A. Without virtual inheritance, D has two copies of A's members — the compiler cannot determine which copy to access. With virtual public A in both B and C, the compiler ensures only one A subobject exists in D, shared between B and C paths. The most-derived class (D) is responsible for initializing the virtual base.

Q: When is multiple inheritance appropriate in C++?

A: Best used for implementing multiple pure interfaces (abstract classes with no data members) — equivalent to Java's multiple interface implementation. Inheriting from multiple concrete classes with data members is complex and should be avoided. The STL uses this: basic_iostream inherits from both basic_istream and basic_ostream via virtual inheritance.

Common Pitfalls

  • Ambiguous member access: If two bases provide a member with the same name, accessing it without explicit qualification (Base::member) is a compile error.
  • Object size with virtual inheritance: Virtual inheritance adds a vptr for the virtual base — objects are larger than with non-virtual inheritance.

Best Practices

  • Restrict multiple inheritance to inheriting from pure-interface abstract classes where possible.
  • Use virtual inheritance when a diamond hierarchy is unavoidable to eliminate the ambiguous base subobject.
  • Prefer composition over multiple inheritance for code reuse — it's simpler, more flexible, and less fragile.