A key idea in object-oriented programming (OOP), inheritance allows for the development of hierarchical class classifications and code reuse.
Inheritance in C++
One class can inherit the traits and abilities of another class through inheritance. It is called a derived class, child class, or subclass, while the class that extends it is called the base class, parent class, or superclass. This relationship is frequently referred to as a “is-a” relationship, which means that an object of the derived class “is a” type of the base class (for example, a MotorHome “is a” particular sort of Car and Home, or an mp3_file “is an” os_file).
Code Reuse through Inheritance
One of inheritance’s biggest benefits is code reuse. A new class that inherits from an older class can use its data members and member functions without redefining them. This removes duplicate code, speeds up development, and improves program stability. After been written and debugged, a base class can be reused or derived to suit different situations.
Interface inheritance enables various derived classes to be used interchangeably through the interface provided by a common base class, which is commonly known as run-time polymorphism, and implementation inheritance saves implementation effort by sharing facilities provided by a base class.
Class Hierarchies
A hierarchy is made up of inheritance-related classes. At the basis of this hierarchy is usually a base class, from which other classes either directly or indirectly inherit. Common members are defined by the base class, whereas particular members are defined by each derived class. A fire engine is a type of truck, which is a type of vehicle, allowing for a logical arrangement of types.
Different types of inheritance
These hierarchies are formed via a variety of inheritance types:
Single Inheritance: In this most used form, a class directly inherits from a single base class. The inheritance of a management class from a worker class serves as an illustration.

Multilevel Inheritance: A class in this structure operates as a base class for a derived class, which turns into a base class for yet another derived class. An inheritance path A -> B -> C, for instance, is formed when class A is a base for B and class B is a base for C. One definition of “intermediate base class” is Class B.

Multiple Inheritance: A class can inherit from multiple base classes at the same time in C++. Combining features from multiple existing classes can be a compelling use case for this. The “diamond problem,” in which a class inherits the same ancestor’s data members more than once through several paths, and confusing name lookup are two complications that can result from it.

Hierarchical Inheritance: This resembles a tree structure in which a single base class has several derived classes branching off from it.

Hybrid Inheritance: Combining two or more inheritance types into one program is what this is.

Virtual Base Classes: Used in multiple inheritance to guarantee that a derived class receives only one copy of a common base class, independent of the number of inheritance pathways, hence resolving ambiguities (such as the “diamond problem”).
Important Factors in Inheritance
Defining Derived Classes: A class derivation list is a list of base classes separated by commas, each of which has an optional access specifier (public, protected, or private). A derived class defines the class or classes it derives from in this list.
Access Control: Users of the derived class can access members inherited from the base class according to the derivation list’s access specifier. In the derived class, for instance, public members of the base class continue to be public due to public inheritance. Outside code cannot access protected members, but derived classes can. To preserve encapsulation, derived classes can never directly access private members of the base class.
Overriding Methods: Using the same prototype, a derived class can redefine a method that is present in its base class. We call this overriding. The scope resolution operator (::) can be used to call the base class method before the derived class adds its own specialisation, or it can implement its own version of the functionality.
Derived-Class Objects and Subobjects: Subobjects for the members defined in the derived class and subobjects for each base class it inherits from make up a derived object conceptually.
Constructors and Destructors: Before the members of the derived class are initialised, the base-class portion of the derived object is initialised using a base-class constructor. Arguments are passed to base-class constructors by derived-class constructors via their initialiser list. Destructors operate in the opposite order: base class destructors are invoked after the derived class destructor. Almost always, base classes should provide a virtual destructor to guarantee that derived class objects are properly cleaned up when they are removed using a base class pointer.
Pointers and References to Base Classes: A base class pointer or reference can be implicitly bound to a derived type object. Polymorphism requires this for virtual functions since the dynamic type of the object determines the function that is executed at runtime.
Code Example: Single Inheritance
The following example illustrates single inheritance using the worker and manager classes:
#include <iostream>
#include <string> // Required for std::string
// Base class declaration
class worker {
protected: // Members are protected so derived classes can access them
int age;
std::string name; // Using std::string for name
public:
// Method to get worker data
void get() {
std::cout << "Your name please: ";
std::cin >> name;
std::cout << "Your age please: ";
std::cin >> age;
}
// Method to display worker data
void show() {
std::cout << "My name is: " << name << std::endl;
std::cout << "My age is: " << age << std::endl;
}
};
// Derived class declaration, inheriting publicly from worker
class manager : public worker {
private:
int numWorkersUnderMe; // Specific data for manager
public:
// Method to get manager-specific data, calls base class get()
void get() {
worker::get(); // Call base class method to get name and age
std::cout << "Number of workers under you: ";
std::cin >> numWorkersUnderMe;
}
// Method to display manager-specific data, calls base class show()
void show() {
worker::show(); // Call base class method to show name and age
std::cout << "Number of workers under me are: " << numWorkersUnderMe << std::endl;
}
};
int main() {
manager m1; // Create an object of the derived class
std::cout << "Enter details for the manager:\n";
m1.get(); // Call the derived class's get() method
std::cout << "\nDisplaying manager details:\n";
m1.show(); // Call the derived class's show() method
return 0;
}
Output
Enter details for the manager:
Your name please: Govindhtech
Your age please: 2
Number of workers under you: 10
Displaying manager details:
My name is: Govindhtech
My age is: 2
Number of workers under me are: 10
Explanation of the Code Example
worker class (Base Class): The common attributes for every employee, such name and age, are defined by this class. The derived class, the manager, can directly access the data members because they are protected, but direct access from outside the class hierarchy is still prohibited. The get() and show() methods are included to manage the input and display of this shared data.
manager class (Derived Class): The worker class is publicly inherited by this class. This implies that all employees who are public and protected also become public and protected employees of the manager.
- numWorkersUnderMe is a unique data member introduced by the management class.
- It takes precedence over the get() and show() functions. Worker::get() and worker::show() are explicitly called in overridden methods using the scope resolution operator (::). After utilising the base class, the derived class customises its capabilities.
main() function
- It creates an object m1 of the manager class. Upon calling m1.get(), it first runs worker::get() to gather the name and age before requesting the manager-specific information.
- The manager’s unique data is displayed by m1.show() after worker::show() has been executed.
- As a manager object, m1 “is a” worker and is capable of carrying out all general worker actions in addition to its specific management operations, as demonstrated in the example. The derived object’s direct access to base class elements is a crucial component of public inheritance.
You can also read Input/Output Operators Overloading In C++ With Code Examples