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

C++ Multiple Inheritance

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 <iostream>

class Flyable {
public:
	void fly() { std::cout << "Flying" << std::endl; }
};

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

class Duck : public Flyable, public Swimmable {};

int main() {
	Duck d;
	d.fly();
	d.swim();
	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 <iostream>

class A {
public:
	A() { std::cout << "A first" << std::endl; }
};

class B {
public:
	B() { std::cout << "B second" << std::endl; }
};

class C : public A, public B {};

int main() {
	C c;
	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 <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 {
public:
	void showA() { A::show(); }
};

int main() {
	C c;
	c.showA();
	return 0;
}

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.