1. Home
C++ Tutorial

Explore C++ Tutorials: Exploring the World of C++ Programming

Discover comprehensive C++ tutorials designed for beginners and advanced programmers alike. Enhance your coding skills with step-by-step guides and practical examples.

  • 77 Lessons
  • 15 Hours
right-top-arrow
21

Multiple Inheritance in C++: A Complete Guide with Examples

Updated on 25/09/2024418 Views

Inheritance allows us to create new classes based on existing ones. It is like building upon a blueprint to create more specialized versions.

Imagine creating a class for "Animal" with properties like name and sound. We can then inherit this base class to create specific animal classes like "Dog" or "Cat." This eliminates the need for us to rewrite common functionalities for each animal class, saving time and effort.

Also, when changes are needed in the base class, all derived classes automatically inherit those changes. This promotes consistency and simplifies maintenance across related classes.

Let us learn all about multiple inheritance in C++ in this tutorial and find out how we can practically use this type of inheritance in C++ programming.

Single Inheritance vs. Multiple Inheritance in C++

In single inheritance, a derived class inherits from one base class. This establishes a clear parent-child relationship between the classes.

Here is an example of the relationship:

Animal (Base Class)

|

v

Dog (Derived Class)

When it comes to multiple inheritance, the derived class inherits from multiple base classes. This allows the derived class to combine functionalities from various sources.

Here is an example of the relationship:

Drawable (Base Class 1) Speakable (Base Class 2)

| |

v v

Dog (Derived Class) - inherits from both ->> Can bark and be drawn

In this example, the Dog class inherits functionalities from both Drawable and Speakable base classes. It can potentially have methods like draw() from Drawable and bark() from Speakable.

Member Access and Inheritance

When a class inherits from another class, it gains access to the members (attributes and methods) of the base class. However, the accessibility of these inherited members depends on the access specifiers used in the base class.

1. Public Members

Public members of the base class become directly accessible by the derived class and its objects. These members can be used as if they were defined in the derived class itself.

2. Private Members

Private members of the base class are not accessible by the derived class or its objects. They are encapsulated within the base class and can only be accessed by member functions of the base class itself.

3. Protected Members

Protected members of the base class become accessible by the derived class and its objects, but not directly accessible by objects of classes further derived from the derived class. Protected members provide a way to control access while allowing derived classes to use them.

Here's a table summarizing the impact of access specifiers:

Base Class Access Specifier

Accessible by Derived Class?

Accessible by Objects of Derived Class?

Public

Yes

Yes

Private

No

No

Protected

Yes

Yes (but not by objects of further derived classes)

Here is an example of the structure:

class Animal {

public:

void eat() { ... } // Public member

private:

std::string name; // Private member

protected:

int age; // Protected member

};

class Dog : public Animal {

public:

void bark() { ... }

// Dog can directly access eat() (public member)

// Dog cannot directly access name (private member)

void getAge() { return age; } // Can access protected member through member function

};

In this multiple inheritance in C++ example, the Dog class inherits the public eat() function but cannot directly access the private name member. It can, however, access the protected age member through its own member function getAge().

Multiple Inheritance Syntax

The syntax for multiple inheritance in C++:

class DerivedClass : public BaseClass1, public BaseClass2 {

// ... members and methods of DerivedClass

};

In the above multiple inheritance syntax, DerivedClass is the name of the class that inherits from multiple base classes.The access specifier public indicates that the members inherited from the base classes become public members of the derived class.

You can also use private or protected to control access differently. BaseClass1 and BaseClass2 are the names of the base classes from which the derived class inherits. You can list as many base classes as needed, separated by commas.

Example:

class Animal {

public:

void eat() { ... }

};

class Drawable {

public:

void draw() { ... }

};

class Dog : public Animal, public Drawable {

public:

void bark() { ... }

};

In this multiple inheritance in C++ example, the Dog class inherits functionalities from both Animal and Drawable. It can potentially have eat() from Animal and draw() from Drawable.

Multiple Inheritance Example Programs in C++

Let us look at two multiple inheritance in C++ program with output examples to understand this type of inheritance better.

Example 1: Shape and Color

This multiple inheritance in C++ example demonstrates how a ColoredShape class can inherit properties from both a Shape class and a Color class:

Code:

#include <iostream>

#include <string>

class Shape {

public:

virtual void draw() = 0; // Pure virtual function (enforces derived classes to implement draw())

};

class Color {

public:

Color(const std::string& color) : m_color(color) {}

std::string getColor() const { return m_color; }

private:

std::string m_color;

};

class ColoredShape : public Shape, public Color {

public:

ColoredShape(const std::string& color, const std::string& shape) : Color(color), m_shape(shape) {}

void draw() override {

std::cout << "Drawing a " << m_shape << " in " << getColor() << " color." << std::endl;

}

private:

std::string m_shape;

};

int main() {

ColoredShape redSquare("red", "square");

redSquare.draw(); // Output: Drawing a square in red color.

return 0;

}

In the above multiple inheritance in C++ example, the Shape class has a pure virtual function draw() that derived classes must implement. This enforces the concept of a shape but leaves the specific drawing behavior to subclasses.

The Color class stores a color string. The ColoredShape class inherits from both Shape and Color, gaining access to their members. Finally, The draw() function in ColoredShape overrides the base class draw() and combines information from both m_shape and getColor() to provide a more descriptive output.

Example 2: Employee and Department

This multiple inheritance in C++ example models an employee with both department affiliation and job title:

Code:

#include <iostream>

#include <string>

class Department {

public:

Department(const std::string& name) : m_name(name) {}

std::string getName() const { return m_name; }

private:

std::string m_name;

};

class Job {

public:

Job(const std::string& title) : m_title(title) {}

std::string getTitle() const { return m_title; }

private:

std::string m_title;

};

class Employee : public Department, public Job {

public:

Employee(const std::string& department, const std::string& jobTitle, const std::string& name)

: Department(department), Job(jobTitle), m_name(name) {}

void introduce() const {

std::cout << "Hello, I'm " << m_name << ", a(n) " << getTitle() << " in the " << getName() << " department." << std::endl;

}

private:

std::string m_name;

};

int main() {

Employee johnDoe("Engineering", "Software Engineer", "John Doe");

johnDoe.introduce(); // Output: Hello, I'm John Doe, a(n) Software Engineer in the Engineering department.

return 0;

}

In this multiple inheritance in C++ example, the Department class stores a department name. The Job class stores a job title. The Employee class inherits from both Department and Job, allowing it to access and use information from both.

Finally, the introduce() function demonstrates how the employee can combine information from department, job title, and name for a self-introduction. If you wish to learn how to code in C++, you can check out upGrad’s software engineering courses.

Ambiguity in Multiple Inheritance in C++

Ambiguity in multiple inheritance arises when a derived class inherits the same member name (function or variable) from two or more base classes. The compiler gets confused about which member function to call when you try to access that member through the derived class object. This is known as the "diamond problem."

Let us understand this with the help of a multiple inheritance cpp example.

Scenario:

Imagine you have three classes:

  • Shape: Base class with a function draw().
  • Colored: Base class with a function draw().
  • ColoredShape: Derived class inheriting from both Shape and Colored.
  • Problem:

Both Shape and Colored define a function named draw(). When you create a ColoredShape object and call draw(), the compiler doesn't know which draw() function to call: the one from Shape or the one from Colored.

Consequences:

  • Compilation error: The compiler throws an error because it cannot determine the intended function.
  • Unexpected behavior: If the error is not caught, the compiler might choose one function arbitrarily, leading to unintended behavior in your program.

Solutions:

There are two main ways to resolve ambiguity in multiple inheritance:

  1. Scoping with the Class Name

You can explicitly call the desired function using the scope resolution operator (::) and the name of the base class:

ColoredShape cs;

cs.Shape::draw(); // Calls the draw() function from Shape

cs.Colored::draw(); // Calls the draw() function from Colored

Scoping can be used for simple cases where you need to call a specific function from a particular base class occasionally.

  1. Virtual Inheritance

By declaring one of the base classes as virtual, you can instruct the compiler to create a single instance of that base class for the inheritance hierarchy, preventing ambiguity. This is a more general solution:

class Shape {

public:

virtual void draw() { ... }

};

class Colored : virtual public Shape { // Declare Shape as virtual

public:

void draw() override { ... } // Override Shape's draw()

};

class ColoredShape : public Colored {

public:

// No need to explicitly call draw(), compiler knows which one to use

};

Virtual inheritance is a more robust solution, especially in complex hierarchies, as it avoids ambiguity throughout the inheritance structure.

Benefits of Multiple Inheritance in C++

While multiple inheritance in C++ offers some advantages, it's important to use it judiciously due to potential complexity. Here are some situations where it can be beneficial:

1. Modeling Complex Relationships

Multiple inheritance allows a derived class to inherit properties and behaviors from multiple base classes, making it suitable for modeling objects with characteristics from various domains.

Example:

Imagine a Robot class. It could inherit from a Machine class for mechanical functionalities like movement and from a Brain class for decision-making capabilities. This inheritance structure effectively captures the essence of a robot that combines mechanical and intelligent aspects.

2. Code Reusability

By inheriting functionalities from multiple base classes, you can avoid code duplication. If specific behaviors are common to several derived classes, inheriting from a shared base class promotes code reuse.

Example:

Consider a game development scenario. You might have a base class Drawable with methods for drawing objects on the screen. Separate base classes like Movable and Collidable could handle movement and collision detection, respectively. Derived classes like Player and Enemy could then inherit from these base classes as needed, reusing common functionalities.

3. Flexibility in Design

Multiple inheritance allows for more flexible class design. A derived class can pick and choose the functionalities it needs from multiple base classes, potentially leading to a more modular and adaptable design.

Final Tips

Multiple inheritance can be a powerful tool when used strategically to model complex relationships between objects. However, its potential pitfalls should be carefully considered.

We should always evaluate alternatives like interfaces or composition for simpler and more maintainable solutions. We must also strive for clarity and maintainability in our object-oriented designs. If you wish to learn programming languages such as C++, you can check out upGrad’s computer science programs such as the Master’s in Computer Science Program.

Frequently Asked Questions

  1. What is multiple inheritance in C++?

Multiple inheritance allows a class to inherit properties and behaviors from more than one base class in C++.

  1. How is multiple inheritance different from single inheritance?

Single inheritance lets a class inherit from only one base class, while multiple inheritance allows inheritance from multiple base classes.

  1. What is multilevel inheritance in C++ with an example?

Multilevel inheritance creates a hierarchy of classes. A class inherits from a derived class, which itself inherits from another base class. For example:

class Animal {

public:

void eat() { ... }

};

class Dog : public Animal {

public:

void bark() { ... }

};

class Poodle : public Dog {

public:

void swim() { ... }

};

  1. What is the "diamond problem" in multiple inheritance?

The diamond problem occurs when two base classes share a common ancestor, and a derived class inherits from both. This creates ambiguity about which member function to call if the base classes have the same member name.

  1. What is multiple inheritance or multilevel inheritance?

These are two different inheritance mechanisms in C++. Multiple inheritance allows inheriting from multiple base classes, while multilevel inheritance creates a class hierarchy through inheritance.

  1. When should I use multiple inheritance?

Use multiple inheritance cautiously. It can model complex relationships but can lead to ambiguity. Consider alternative approaches like interfaces or composition first.

  1. What are the advantages of multiple inheritance?

Multiple inheritance models complex real-world relationships effectively. It also promotes code reusability by inheriting functionalities from multiple sources.

  1. What are the drawbacks of multiple inheritance?

Multiple inheritance increases code complexity and the potential for ambiguity (diamond problem). It also makes code harder to maintain and understand.

Abhimita Debnath

Abhimita Debnath

Abhimita Debnath is one of the students in UpGrad Big Data Engineering program with BITS Pilani. She's a Senior Software Engineer in Infosys. She…Read More

Need Guidance? We're Here to Help!
form image
+91
*
By clicking, I accept theT&Cand
Privacy Policy
image
Join 10M+ Learners & Transform Your Career
Learn on a personalised AI-powered platform that offers best-in-class content, live sessions & mentorship from leading industry experts.
right-top-arrowleft-top-arrow

upGrad Learner Support

Talk to our experts. We’re available 24/7.

text

Indian Nationals

1800 210 2020

text

Foreign Nationals

+918045604032

Disclaimer

upGrad does not grant credit; credits are granted, accepted or transferred at the sole discretion of the relevant educational institution offering the diploma or degree. We advise you to enquire further regarding the suitability of this program for your academic, professional requirements and job prospects before enr...