Four pillars of Object-Oriented Programming
It is indisputable that C++ is as vast as it can get. And to support this sprawling structure, C++ takes the support of 4 essential “pillars”. These pillars are:
This article focuses on the Inheritance pillar and describes in detail the various concepts associated with Inheritance in C++.
What is Inheritance in C++?
It's a feature that lets one class inherit traits and characteristics from another. Because the derived class or the child class can inherit the members of the base class, inheritance allows you to reuse your code. Inheritance in C++ works the same way as in biology, the children show the same features/functions as their parents.
Why is Inheritance in C++ important?
- Data abstraction
- Transitive nature
1. Data abstraction
Generic (base) classes may manage general traits and abilities, whereas derived classes can organize specializations in hierarchical connections. Complex situations and relationships become simpler to manage as a result of this. For instance, if the Parent class is Car, it may contain all functions common to all cars, while a Child class named Tesla may contain functions unique to a Tesla, while also inheriting all functions of the Car class.
You may reuse and change the classes you've created and tested to fulfill new jobs. It is not necessary to know the implementation of the base class for this purpose; only the public interfaces are required. For instance, considering the previous example of a Car class, all Child classes (Maruti, Volkswagen, Ford, Hyundai) may simply inherit all functions from the Car class, instead of writing these functions from scratch every time.
3. Transitive nature
Inheritance helps to establish an Is_a relationship between the child class and the parent class. Say, if Child_AA inherits properties of Child_A, which in turn inherits properties of Parent_A, then Child_AA has a transitive relationship with Parent_A.
Such a structure makes debugging easier; since only one copy of the code lies with the Parent_A, you need to simply change and test the code in Parent_A and all derived classes will be automatically debugged. For instance, say the Parent_A class is Car, Child_A class is Tesla, and Child_AA class is Tesla_Model_3. Here, Tesla_Model_3 will inherit all features of the Car class transitively.
Test your understanding
Q1. Inheritance in C++ deals with the concept of child/derivable class derived from base/parent class.
Q2. Which of the following is not an advantage of Inheritance?
- Simplifies overall code due to abstraction
- Increases the reusability of code
- Helps establish a transitive relationship between various classes.
- Allows us to have different implementations of the same function depending upon which class inherits it.
Types of Inheritance
The 5 types of inheritance in C++ include:
- Single Inheritance
- Multilevel Inheritance
- Multiple Inheritance
- Hierarchical Inheritance
- Hybrid Inheritance
Let’s look at each type of inheritance one by one.
In Single inheritance, there is only one derived class from a base class. The following code snippet shows a Child class derived from the Parent class. When an object of the Child class is created, the Parent class is initialized first, and then the Child class is executed. However, when an object of the Parent class is declared, only the Parent class gets executed.
In Multiple inheritance, one Child class is derived from more than one Parent class. As with Single inheritance, when the child class is called, both the parent classes are initiated before it.
As with evolution, a child further has a child. Similarly, a derived class in Multilevel inheritance further acts as a base class for another derived class.
Try it yourself
Try to write the code for Multilevel inheritance yourself. You may take help from the code snippets provided above. If you face any problems, feel free to reach out to us in the comments below!
In this type of inheritance, more than one subclass is derived from more than one base class.
Any combination of the above-mentioned four types of inheritance falls under the category of Hybrid inheritance.
Test your understanding
Q1. Which among the following is false?
a) If one class inherits the inherited class in single-level inheritance, it is a multi-level inheritance
b) Hybrid inheritance always contains multiple inheritance
c) Hierarchical inheritance involves inheriting the same class into more than one classes
d) Hybrid inheritance can involve any type of inheritance together
Q2. How many classes can be inherited by a single class in multiple inheritance (C++)?
a) Only 2
b) Only 27
c) Only 1024
d) Any number of classes can be inherited
Q3. Which of the following types of inheritance causes the diamond problem? A diamond problem arises if Parent_A derives Child_A and Child_B, both of which further derives Child_AB. In this case, all functions of Child_A and Child_B are copied twice into Child_AB, resulting in an anomaly.
a) Single level
Okay, so far so good? Good.
Now comes the critical part, so pay attention!
To ensure the ‘safety’ of functions in the base class, C++ has 3 types of access specifiers. These access specifiers allow us to specify which features should be publicly available to derived classes, protected or inaccessible.
These three access specifiers are:
A derived class inherits all base class methods with the following exceptions:
- Destructors, constructors, and copy constructors of the parent class.
- Overloaded operators of the base class.
- The friend functions of the base class.
Access specifiers are mentioned at two places: within a class while defining functions, and while defining child classes. Both these access specifiers are separate, and it is the combination of these that eventually predicts the accessibility of a function in a class.
Public visibility mode
The public and protected members defined in the base class are public and protected members in the derived class. As a result, the derived class and all other classes may access the public members of the base class. Only the derived class and its members have access to the protected members of the base class. The derived class, on the other hand, has no access to the private members of the base class.
Protected visibility mode
Public and protected of the base class become protected members of the derived class when the protected visibility mode is enabled. Only the derived class and its member functions have access to these members now. These members can also be inherited, and the inherited subclasses will have access to them. Private members of the base class remain inaccessible to the derived class.
Private visibility mode
Public and protected base class members become private in the derived class when the private visibility mode is enabled. This prevents these members' access outside of the derived class. Only the derived class's member functions have access to them. These members cannot be inherited. The private members of the base class are, as always, inaccessible to the derived class.
Assume that the member functions of the base and derived classes have the same name and arguments. When we create an object of the derived class and try to access the member function, the derived class's member function is called instead of the base class's. The derived class's member function takes precedence over the base class's member function. This is called function overriding in C++.
Congratulations! You have learned all essential concepts of Inheritance in C++. Practice and you will master these in no time. In case you get confused, feel free to reach out to us and we would be glad to help!
Happy Coding :)