Multiple Inheritance is a feature in object-oriented programming where a class can inherit from more than one base class. This allows a derived class to acquire properties and behaviors (attributes and methods) from multiple parent classes, enabling the reuse of code from different sources.
In C++, a class can derive from multiple classes, which gives it access to the attributes and methods of all its base classes.
FlyingCar class can inherit from both Car (has-a relationship) and FlyingMachine (has-a relationship), but it also is-a Car and is-a FlyingMachine at the same time.In C++, you can inherit from multiple base classes using a comma-separated list of base classes in the class definition.
class DerivedClass : public BaseClass1, public BaseClass2 {
// Derived class code
};
Consider a situation where we want to create a class FlyingCar, which inherits from two base classes: Car (for car-like behaviors) and FlyingMachine (for flying behaviors).
#include <iostream>
using namespace std;
// Base class 1: Car
class Car {
public:
void drive() {
cout << "Driving the car" << endl;
}
};
// Base class 2: FlyingMachine
class FlyingMachine {
public:
void fly() {
cout << "Flying the flying machine" << endl;
}
};
// Derived class: FlyingCar, inheriting from both Car and FlyingMachine
class FlyingCar : public Car, public FlyingMachine {
public:
void display() {
cout << "This is a flying car!" << endl;
}
};
int main() {
// Creating an object of FlyingCar
FlyingCar fc;
// Using methods from both base classes
fc.drive(); // Method from Car
fc.fly(); // Method from FlyingMachine
fc.display(); // Method from FlyingCar
return 0;
}
Car class has a method drive(), which represents car-specific behavior.FlyingMachine class has a method fly(), which represents flying behavior.FlyingCar class is derived from both Car and FlyingMachine. It can call the methods drive() and fly(), inherited from both base classes, as well as its own method display().Driving the car
Flying the flying machine
This is a flying car!
Although multiple inheritance can be powerful, it comes with certain complexities and potential problems. These include:
The diamond problem occurs when a class inherits from two classes that both have a common base class. This can cause ambiguity about which version of the base class’s methods and attributes should be inherited by the derived class. It leads to confusion because the derived class may inherit the same member or function from both paths in the inheritance hierarchy.
#include <iostream>
using namespace std;
// Base class 1
class Animal {
public:
void sound() {
cout << "Animal sound!" << endl;
}
};
// Base class 2
class Dog : public Animal {
public:
void sound() {
cout << "Dog barking!" << endl;
}
};
// Base class 3
class Cat : public Animal {
public:
void sound() {
cout << "Cat meowing!" << endl;
}
};
// Derived class
class Pet : public Dog, public Cat {
// Pet class has both Dog and Cat classes as base classes
};
int main() {
Pet myPet;
myPet.sound(); // Which sound() method should be called?
return 0;
}
In the example, the Pet class inherits from both Dog and Cat, which both inherit from the Animal class. The Dog and Cat classes each override the sound() method from Animal, and the Pet class now has two sound() methods (one from Dog and one from Cat). The compiler is unsure which sound() method to call, leading to ambiguity.
The diamond problem can be solved using virtual inheritance, which ensures that only one instance of the common base class (Animal in this case) is inherited, avoiding duplication and ambiguity. This allows the derived class to avoid inheriting multiple copies of the same base class.
#include <iostream>
using namespace std;
// Virtual base class
class Animal {
public:
void sound() {
cout << "Animal sound!" << endl;
}
};
// Base class 1 inheriting virtually from Animal
class Dog : virtual public Animal {
public:
void sound() {
cout << "Dog barking!" << endl;
}
};
// Base class 2 inheriting virtually from Animal
class Cat : virtual public Animal {
public:
void sound() {
cout << "Cat meowing!" << endl;
}
};
// Derived class inheriting from Dog and Cat
class Pet : public Dog, public Cat {
// No ambiguity now due to virtual inheritance
};
int main() {
Pet myPet;
myPet.sound(); // Which sound() method should be called? Now there is no ambiguity.
return 0;
}
In this code:
Dog and Cat classes inherit from Animal virtually, ensuring that only one instance of Animal exists in the Pet class.sound() method now, from the Pet class’s effective single Animal instance.Dog barking!
In this case, even though Pet inherits from both Dog and Cat, the Pet class calls the sound() method from the Dog class, which is now correctly inherited via virtual inheritance.
Code Reusability: Multiple inheritance allows the derived class to reuse code from multiple base classes, avoiding redundancy and making it easier to extend the functionality of existing classes.
Combining Behaviors: It enables a class to combine multiple behaviors. For example, a FlyingCar class can combine the behaviors of both Car and FlyingMachine, allowing it to inherit both driving and flying capabilities.
Expressing Complex Real-World Relationships: Multiple inheritance allows us to represent more complex relationships between objects. For example, a Smartphone might inherit both from Phone (communication) and Camera (photography), combining multiple functionalities.
Complexity and Ambiguity: Multiple inheritance can increase the complexity of the system, making it harder to maintain. The diamond problem, which causes ambiguity in method calls, is one of the major issues that arise in multiple inheritance.
Tight Coupling: The derived class becomes tightly coupled with all the base classes. Changes in the base classes may propagate to the derived class, making the system harder to maintain.
Increased Memory Consumption: If multiple copies of base classes are inherited, it can lead to higher memory usage. Virtual inheritance resolves this to an extent but adds overhead.
Open this section to load past papers