← Back to C++ Course | Chapter 9: Inheritance | Lesson 4 of 8

C++ Multiple Inheritance

Multiple inheritance is when a class learns from more than one parent, like a child picking up skills from both mom and dad. It can cause confusion when both have the same thing.
Syntax
cpp
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

cpp
// 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;
}

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

cpp
// 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;
}

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

cpp
#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;
}

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

cpp
#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;
}

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

cpp
// 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;
}
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
Common Mistakes
  1. Calling a member that both base classes define without qualifying it, which is ambiguous.
  2. Ignoring the diamond problem, which gives the most-derived class two copies of a shared base.
  3. Not qualifying with the base class name, as in A::show(), to resolve ambiguity.

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.