Inheritance is one of the four main pillars of Object-Oriented Programming (OOP), along with Encapsulation, Abstraction, and Polymorphism.
Definition:
“Inheritance is the process by which one class acquires the properties (data) and behaviors (functions) of another class.”
In simple words, it means we can create a new class (child or derived class) based on an existing class (parent or base class) so that the new one can reuse and extend the existing functionality.
2. Why Do We Use Inheritance?
Contents
- 2. Why Do We Use Inheritance?
- 3. Basic Syntax of Inheritance
- 4. Example: Simple Inheritance
- Explanation:
- 5. How Constructors Work in Inheritance
- Example:
- Explanation:
- 5.1 How Destructors Work in Inheritance
- Example:
- Explanation:
- Constructor and Destructor Behavior Summary Table
- 5.2 Access Specifiers and Inheritance
- 6. Types of Inheritance
- 6.1 Single Inheritance
- 6.2 Multilevel Inheritance
- 6.3 Hierarchical Inheritance
- 6.4 Multiple Inheritance
- 6.5 Hybrid Inheritance
- Explanation:
- 8. Virtual Base Classes – Solving the Diamond Problem
- Share this:
Let’s take a real-life situation:
Suppose we are building a School Management System.
We start with a general class Employee that stores data like name, ID, and salary.
Now, we want to create a Teacher class. We could copy all variables again, but that’s code repetition — not a good practice.
Instead, we let Teacher inherit from Employee.
This way, all common properties (name, ID, salary) come automatically from Employee.
We just add new features like subject or department.
Purpose of inheritance:
“To promote code reuse and avoid rewriting the same logic again and again.”
3. Basic Syntax of Inheritance
Inheritance is declared in C++ using a colon (:) after the class name, followed by an access specifier (usually public) and the base class name.
class Base {
// members of base class
};
class Derived : public Base {
// members of derived class
};
Here,
Base
→ Parent (or base) classDerived
→ Child (or derived) classpublic
→ Access specifier
The public
keyword means that public members of the base class remain public in the derived class.
4. Example: Simple Inheritance
Let’s write a simple program showing Teacher inheriting from Employee.
#include <iostream>
using namespace std;
class Employee {
public:
string name;
int id;
void displayInfo() {
cout << "Name: " << name << endl;
cout << "ID: " << id << endl;
}
};
class Teacher : public Employee {
public:
string subject;
void displayTeacher() {
displayInfo(); // calling base class function
cout << "Subject: " << subject << endl;
}
};
int main() {
Teacher t;
t.name = "Dr. Afzal";
t.id = 101;
t.subject = "Computer Science";
t.displayTeacher();
return 0;
}
Output:
Name: Dr. Afzal
ID: 101
Subject: Computer Science
Explanation:
- The Teacher class automatically gets the name and id fields and the function displayInfo() from Employee.
- It adds a new field subject and a new function displayTeacher().
- This shows how code reusability works in inheritance.
5. How Constructors Work in Inheritance
Constructors are special functions that run automatically when an object is created.
When a derived class is created, the base class constructor runs first, followed by the derived class constructor.
Example:
#include <iostream>
using namespace std;
class Employee {
public:
Employee() {
cout << "Employee constructor called" << endl;
}
};
class Teacher : public Employee {
public:
Teacher() {
cout << "Teacher constructor called" << endl;
}
};
int main() {
Teacher t;
return 0;
}
Output:
Employee constructor called
Teacher constructor called
Explanation:
- When we create an object of Teacher, C++ first calls the Employee constructor (the base part of the object).
- After that, the Teacher constructor is executed.
- This ensures that the base class part is properly set up before the derived class adds its own data.
5.1 How Destructors Work in Inheritance
Destructors are special functions that are called automatically when an object goes out of scope or is deleted. They are used to release resources like memory, files, or network connections. In inheritance, destructors are called in the reverse order of constructors.
Example:
#include <iostream>
using namespace std;
class Base {
public:
~Base() {
cout << "Base Destructor called" << endl;
}
};
class Derived : public Base {
public:
~Derived() {
cout << "Derived Destructor called" << endl;
}
};
int main() {
Derived d; // Constructor of Base then Derived runs automatically.
// When program ends, destructors run in reverse order.
return 0;
}
Output:
Derived Destructor called
Base Destructor called
Explanation:
- When the program finishes or the object goes out of scope, C++ first calls the destructor of the derived class, then the base class.
- This ensures that resources of the derived class are released first, followed by cleanup of the base class.
- This sequence is the opposite of constructor execution order.
Constructor and Destructor Behavior Summary Table
Aspect | Constructor Behavior | Destructor Behavior |
---|---|---|
Execution Order | Base → Derived | Derived → Base |
Purpose | Initialize objects and allocate resources | Clean up and release resources |
Automatic Invocation | Automatically called when an object is created | Automatically called when an object goes out of scope or is deleted |
Virtual in Base Class | Constructors cannot be virtual | Destructors can be virtual (important in polymorphism) |
Memory Management Role | Prepares object for use | Ensures proper deallocation |
This table summarizes how constructors and destructors behave in inheritance, highlighting their sequence and key characteristics.
5.2 Access Specifiers and Inheritance
C++ has three access specifiers:
Specifier | Meaning |
---|---|
public | Accessible everywhere |
protected | Accessible in the same class and derived classes |
private | Accessible only in the same class |
When you use inheritance, the access level of base class members may change depending on the inheritance type.
Access Specifier | Same Class | Derived Class | Outside World |
---|---|---|---|
public | ✅ | ✅ | ✅ |
protected | ✅ | ✅ | ❌ |
private | ✅ | ❌ | ❌ |
This table visually summarizes access levels and their visibility in different contexts.
6. Types of Inheritance
C++ supports several forms of inheritance. Each form defines how classes relate to one another.
- Single Inheritance
- Multilevel Inheritance
- Hierarchical Inheritance
- Multiple Inheritance
- Hybrid Inheritance
6.1 Single Inheritance

In single inheritance, a class is derived from one base class only.
#include <iostream>
using namespace std;
class Animal {
public:
void eat() { cout << "Eating...\n"; }
};
class Dog : public Animal {
public:
void bark() { cout << "Barking...\n"; }
};
int main() {
Dog d;
d.eat();
d.bark();
}
Output:
Eating...
Barking...
6.2 Multilevel Inheritance
A derived class can act as a base class for another derived class.
#include <iostream>
using namespace std;
class Person {
public:
string name;
};
class Employee : public Person {
public:
int id;
};
class Teacher : public Employee {
public:
string subject;
void show() {
cout << "Name: " << name << ", ID: " << id << ", Subject: " << subject << endl;
}
};
int main() {
Teacher t;
t.name = "Sara";
t.id = 10;
t.subject = "Mathematics";
t.show();
}
Output:
Name: Sara, ID: 10, Subject: Mathematics
6.3 Hierarchical Inheritance
One base class is inherited by multiple derived classes.
#include <iostream>
using namespace std;
class Shape {
public:
void draw() { cout << "Drawing shape...\n"; }
};
class Circle : public Shape {
public:
void area() { cout << "Calculating area of circle...\n"; }
};
class Rectangle : public Shape {
public:
void area() { cout << "Calculating area of rectangle...\n"; }
};
int main() {
Circle c;
Rectangle r;
c.draw();
r.draw();
c.area();
r.area();
}
Output:
Drawing shape...
Drawing shape...
Calculating area of circle...
Calculating area of rectangle...
6.4 Multiple Inheritance
A class can inherit from more than one base class.
#include <iostream>
using namespace std;
class Person {
public:
string name;
void setName(string n) { name = n; }
};
class Worker {
public:
int hoursWorked;
void setHours(int h) { hoursWorked = h; }
};
class Engineer : public Person, public Worker {
public:
void display() {
cout << "Name: " << name << endl;
cout << "Hours Worked: " << hoursWorked << endl;
}
};
int main() {
Engineer e;
e.setName("Ali");
e.setHours(40);
e.display();
}
Output:
Name: Ali
Hours Worked: 40
6.5 Hybrid Inheritance
Hybrid inheritance is a combination of two or more types of inheritance. It often results in the Diamond Problem, which can be resolved using virtual base classes.
#include <iostream>
using namespace std;
class A {
public:
void show() { cout << "Class A\n"; }
};
class B : virtual public A {};
class C : virtual public A {};
class D : public B, public C {};
int main() {
D obj;
obj.show();
}
Output:
Class A
Explanation:
Here, A is inherited virtually to avoid duplication. Hybrid inheritance combines features of multiple, multilevel, and hierarchical inheritance.
8. Virtual Base Classes – Solving the Diamond Problem
To avoid duplication of the common base class, we declare it as a virtual base class.
Definition:
“A virtual base class ensures that only one shared copy of the base class is inherited, even when it appears multiple times in the inheritance hierarchy.”
#include <iostream>
using namespace std;
class A {
public:
void show() { cout << "Class A\n"; }
};
class B : virtual public A {};
class C : virtual public A {};
class D : public B, public C {};
int main() {
D obj;
obj.show();
}
Output:
Class A
Because A is inherited virtually, only one copy of A exists in D, even though B and C both derive from it. This removes ambiguity and saves memory.