thecodex.expert · The Codex Family of Knowledge
C++

Multiple Inheritance

When two base classes share a common ancestor, a derived class inheriting from both ends up with two separate copies of that ancestor’s data — the famous diamond problem, and virtual inheritance is C++’s fix.

C++20 / C++23 The diamond problem Last verified:
Canonical Definition

class Derived : public Base1, public Base2 lets Derived inherit from both Base1 and Base2 simultaneously — genuinely different from Java's single-class-inheritance restriction. This introduces the diamond problem: if Base1 and Base2 both derive from a common Base, an ordinary Derived object ends up with two separate, independent copies of Base's data, one via each path, which is rarely what's intended. virtual inheritance (marking the inheritance from the shared ancestor as virtual in both Base1 and Base2) fixes this by ensuring only one shared copy of Base exists in the final object.

Basic multiple inheritance

Duck genuinely has both fly() and swim(), inherited from two entirely separate base classes — something Java's single-inheritance model would require an interface for, but here both bases can carry real implementation.

C++basic_multiple.cpp
class Flyable {
public:
    void fly() { std::cout << "Flying\n"; }
};

class Swimmable {
public:
    void swim() { std::cout << "Swimming\n"; }
};

class Duck : public Flyable, public Swimmable {   // inherits from BOTH
};

Duck d;
d.fly();    // from Flyable
d.swim();   // from Swimmable

The diamond problem

Without virtual inheritance, D ends up with TWO separate, independent copies of A's data — one inherited via B, one via C — and d.value is genuinely ambiguous, since the compiler doesn't know which copy you mean.

C++diamond_problem.cpp
class A {
public:
    int value = 0;
};

class B : public A { };   // B has its OWN copy of A
class C : public A { };   // C has its OWN, SEPARATE copy of A

class D : public B, public C { };   // D ends up with TWO copies of A's value!

D d;
// d.value = 5;   // COMPILE ERROR: ambiguous — which copy, via B or via C?
d.B::value = 5;      // must disambiguate explicitly

virtual inheritance: the fix

With virtual on both B's and C's inheritance from A, D ends up with exactly ONE shared copy of A — d.value is now unambiguous, resolving the diamond problem at its root.

C++virtual_inheritance.cpp
class A {
public:
    int value = 0;
};

class B : public virtual A { };   // virtual inheritance
class C : public virtual A { };   // both share ONE A

class D : public B, public C { };

D d;
d.value = 5;   // no ambiguity now — there's genuinely only one A

Sources

1
ISO/IEC 14882 (C++ Standard), "Derived classes" and "Virtual base classes," cppreference.com/w/cpp/language/derived_class.