Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Diamond Inheritance | Inheritance Overview
C++ OOP
course content

Contenido del Curso

C++ OOP

C++ OOP

1. Fundamentals of OOP
2. Constructors and Destructors
3. Encapsulation Overview
4. Inheritance Overview
5. Polymorphism Overview

bookDiamond Inheritance

Multiple inheritance can lead to a situation known as the diamond problem or diamond inheritance, which is a significant challenge in object-oriented programming languages that support multiple inheritance.

This occurs when a subclass inherits from two or more classes, which themselves inherit from a common superclass. The term diamond is used because the inheritance scheme resembles the shape of a diamond.

cpp

main

copy
1234567
class Base {}; class Derived1 : public Base {}; class Derived2 : public Base {}; class Diamond : public Derived1, public Derived2 {};

The primary issue with diamond inheritance is the ambiguity it creates. Since Diamond inherits from both Derived1 and Derived2, which in turn inherit from Base, there are two copies of Base within an object of Diamond. This can lead to ambiguity. For example:

cpp

main

copy
123456789101112131415
#include <iostream> class Base { public: void display() { std::cout << "Base display()" << std::endl; } }; class Derived1 : public Base { }; class Derived2 : public Base { }; class Diamond : public Derived1, public Derived2 { }; int main() { Diamond obj; obj.display(); // Ambiguity: Which display() method should be called? }

Solution to the problem

The virtual keyword helps to avoid this problem. You can address this ambiguity through virtual inheritance, using the virtual keyword. When a Diamond is inherited virtually, C++ ensures that only one copy of the superclass is present, even if it is inherited multiple times through different paths.

cpp

main

copy
1234567
class Base {}; class Derived1 : virtual public Base {}; class Derived2 : virtual public Base {}; class Diamond : public Derived1, public Derived2 {};

Note

Try to resolve the ambiguity issue in the previous example by utilizing virtual inheritance.

Implementing Diamond Inheritance

To implement diamond inheritance effectively:

  1. use the virtual keyword in the superclass declaration in the intermediate classes;
  2. ensure consistent use of virtual inheritance in all paths of the inheritance hierarchy;
  3. be mindful of constructor and destructor calls order.

Resolving Ambiguities

One of the challenges of multiple inheritance is also dealing with potential ambiguities when it comes to members with the same names.

cpp

main

copy
12345678910111213141516171819
#include <iostream> class Base {}; class Derived1 : public Base { public: void display() { std::cout << "Derived1 display()" << std::endl; } }; class Derived2 : public Base { public: void display() { std::cout << "Derived2 display()" << std::endl; } }; class Diamond : public Derived1, public Derived2 { }; int main() { Diamond obj; obj.display(); // Ambiguity: Which display() method should be called? }

If both superclass have members with the same name, the subclass may not know which one to use. To resolve such ambiguities, you can use the scope resolution operator (::) to specify which base class's member you want to access. For example:

cpp

main

copy
1234567891011121314151617181920
#include <iostream> class Base {}; class Derived1 : public Base { public: void display() { std::cout << "Derived1 display()" << std::endl; } }; class Derived2 : public Base { public: void display() { std::cout << "Derived2 display()" << std::endl; } }; class Diamond : public Derived1, public Derived2 { }; int main() { Diamond obj; obj.Derived1::display(); obj.Derived2::display(); }

¿Todo estuvo claro?

¿Cómo podemos mejorarlo?

¡Gracias por tus comentarios!

Sección 4. Capítulo 5
some-alt