C++ Multiple Inheritance
In this page:
class Base1 { };
class Base2 { };
class Derived : public Base1, public Base2 { };
Introduction to Multiple Inheritance
Multiple inheritance happens when a single derived class inherits from more than one base class simultaneously, letting it combine behavior from several unrelated sources into one type — a capability many other OOP languages deliberately omit.
Example: Introduction to Multiple Inheritance
// Include std::cout and std::cin
#include <iostream>
// Define the type Flyable
class Flyable {
// Members below can be accessed from outside the class
public:
void fly() { std::cout << "Flying" << std::endl; }
};
// Define the type Swimmable
class Swimmable {
// Members below can be accessed from outside the class
public:
void swim() { std::cout << "Swimming" << std::endl; }
};
class Duck : public Flyable, public Swimmable {};
// Program execution starts in main()
int main() {
Duck d;
d.fly();
d.swim();
// Return 0 to signal that the program finished successfully
return 0;
}
Login to try C/C++/Java/PHP code in the editor
Constructor Call Order
With multiple base classes, their constructors run in the exact order those base classes are listed in the derived class's inheritance declaration, not in the order the derived constructor's initializer list happens to write them.
Example: Constructor Call Order
// Include std::cout and std::cin
#include <iostream>
// Define the type A
class A {
// Members below can be accessed from outside the class
public:
A() { std::cout << "A first" << std::endl; }
};
// Define the type B
class B {
// Members below can be accessed from outside the class
public:
B() { std::cout << "B second" << std::endl; }
};
class C : public A, public B {};
// Program execution starts in main()
int main() {
C c;
// Return 0 to signal that the program finished successfully
return 0;
}
Login to try C/C++/Java/PHP code in the editor
The Ambiguity Problem
If two of the base classes each declare a member function with the same name, calling that name on the derived class becomes ambiguous, and the compiler refuses to guess which one you meant — you get a compile error until you explicitly qualify which base's version you want.
Example: The Ambiguity Problem
#include <iostream>
class A {
public:
void show() { std::cout << "A::show" << std::endl; }
};
class B {
public:
void show() { std::cout << "B::show" << std::endl; }
};
class C : public A, public B {};
int main() {
C c;
// c.show(); would fail to compile: ambiguous between A::show and B::show
c.A::show();
return 0;
}
Login to try C/C++/Java/PHP code in the editor
Diamond Problem Introduction
The diamond problem arises when a derived class inherits from two base classes that both, in turn, inherit from the very same grandparent class.
Without special handling, the derived class ends up containing two separate copies of that shared grandparent's data.
Example: Diamond Problem Introduction
#include <iostream>
class Grandparent {
public:
int value = 1;
};
class ParentA : public Grandparent {};
class ParentB : public Grandparent {};
class Child : public ParentA, public ParentB {};
int main() {
Child c;
// c.value would fail to compile: two ambiguous copies of Grandparent
std::cout << c.ParentA::value << std::endl;
return 0;
}
Login to try C/C++/Java/PHP code in the editor
Solving Ambiguity with Member Access
You can resolve name ambiguity between base classes by writing small helper functions in the derived class that explicitly redirect a call to one specific base's version, using the scope resolution operator to disambiguate which parent's member you mean.
Example: Solving Ambiguity with Member Access
// Include std::cout and std::cin
#include <iostream>
// Define the type A
class A {
// Members below can be accessed from outside the class
public:
void show() { std::cout << "A::show" << std::endl; }
};
// Define the type B
class B {
// Members below can be accessed from outside the class
public:
void show() { std::cout << "B::show" << std::endl; }
};
class C : public A, public B {
public:
void showA() { A::show(); }
};
// Program execution starts in main()
int main() {
C c;
c.showA();
// Return 0 to signal that the program finished successfully
return 0;
}
Login to try C/C++/Java/PHP code in the editor
- Calling a member that both base classes define without qualifying it, which is ambiguous.
- Ignoring the diamond problem, which gives the most-derived class two copies of a shared base.
- Not qualifying with the base class name, as in
A::show(), to resolve ambiguity.
Chapter Quiz — Complete all 8 topics to unlock
0/8 topics done
Complete these topics first: