For working professionals
For fresh graduates
More
Explore C++ Tutorials: Explori…
1. The Ultimate C++ Guide: C++ Tutorial for Beginners
2. Application of C++
3. C++ Hello World Program
4. C++ Variable
5. Reference Variable in C++
6. Function Overloading in C++
7. Functions in C++
8. Pointer in C++
9. Data Types in C++
10. C++ for Loop
11. While Loop in C++
12. C++ Lambda
13. Loop in C++
14. Switch Case in C++
15. Array in C++
16. Strings in C++
17. Substring in C++
18. Class and Object in C++
19. Constructor in C++
20. Copy Constructor in C++
21. Destructor in C++
22. Multiple Inheritance in C++
Now Reading
23. Encapsulation in C++
24. Single Inheritance in C++
25. Friend Class in C++
26. Hierarchical Inheritance in C++
27. Virtual Base Class in C++
28. Abstract Class in C++
29. Vector in C++
30. Map in C++
31. Pair in C++
32. Initialize Vector in C++
33. Iterators in C++
34. Queue in C++
35. Priority Queue in C++
36. Stack in C++
37. ifstream in C++
38. Exception Handling in C++
39. Memory Management in C++
40. Templates in C++
41. Type Conversion in C++
42. Enumeration in C++
43. Namespace in C++
44. Set Precision in C++
45. Stringstream in C++
46. Recursion in C++
47. Random Number Generator in C++
48. C++ Shell
49. Setw in C++
50. Multithreading in C++
51. Atoi in C++
52. Call by Value and Call by Reference in C++
53. Difference Between C and C++
54. C# vs C++
55. C++ GUI
56. C++ Game Code
57. Class in C++
58. C++ Header Files
59. Power Function in C++
60. Data Hiding in C++
61. Inline Function in C++
62. Getline Function in C++
63. Cin in C++
64. Printf in C++
65. Struct in C++
66. C++ List
67. static_cast in C++
68. C++ Comments
69. Structures in C++
70. C++ Standard Template Library (STL)
71. Virtual Function in C++
72. Sorting in C++
73. Polymorphism in C++
74. Oops Concepts in C++
75. Converting Integers to Strings in C++
76. Differences Between Break and Continue
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.
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.
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.
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.
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.
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().
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.
Let us look at two multiple inheritance in C++ program with output examples to understand this type of inheritance better.
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.
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 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:
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:
Solutions:
There are two main ways to resolve ambiguity in multiple inheritance:
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.
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.
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:
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.
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.
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.
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.
Multiple inheritance allows a class to inherit properties and behaviors from more than one base class in C++.
Single inheritance lets a class inherit from only one base class, while multiple inheritance allows inheritance from multiple base classes.
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() { ... }
};
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.
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.
Use multiple inheritance cautiously. It can model complex relationships but can lead to ambiguity. Consider alternative approaches like interfaces or composition first.
Multiple inheritance models complex real-world relationships effectively. It also promotes code reusability by inheriting functionalities from multiple sources.
Multiple inheritance increases code complexity and the potential for ambiguity (diamond problem). It also makes code harder to maintain and understand.
Author
Start Learning For Free
Explore Our Free Software Tutorials and Elevate your Career.
Talk to our experts. We are available 7 days a week, 9 AM to 12 AM (midnight)
Indian Nationals
1800 210 2020
Foreign Nationals
+918045604032
1.The above statistics depend on various factors and individual results may vary. Past performance is no guarantee of future results.
2.The student assumes full responsibility for all expenses associated with visas, travel, & related costs. upGrad does not provide any a.