C++ Inheritance
Complete Learning Guide with Examples
Single Multiple Multilevel Hierarchical Hybrid
Covers all inheritance types · Real-world examples · Best practices
C++11 / C++14 / C++17 compatible
C++ Inheritance — Complete Guide Page 2
Table of Contents
1. What is Inheritance?
2. Access Specifiers
3. Single Inheritance
4. Multilevel Inheritance
5. Multiple Inheritance
6. Hierarchical Inheritance
7. Hybrid Inheritance
8. Function Overriding
9. Virtual Functions & Polymorphism
10. Abstract Classes & Pure Virtual
11. Constructors & Destructors in Inheritance
12. Common Mistakes & Best Practices
C++ Inheritance Learning Guide • All examples compile with g++ -std=c++17
C++ Inheritance — Complete Guide Page 3
1. What is Inheritance?
Inheritance is one of the four pillars of Object-Oriented Programming (OOP). It allows a derived
class (child) to acquire the properties and behaviours of a base class (parent), promoting code
reuse and logical hierarchy.
Base Class (Animal) → inherits → Derived Class (Dog)
name, age, eat() breed, bark() + all from Animal
Syntax
class DerivedClass : access_specifier BaseClass {
// derived class members
};
Why use Inheritance?
✔ Reuse existing code ✔ Reduce redundancy ✔ Model real-world relationships ✔ Enable
polymorphism
2. Access Specifiers in Inheritance
The access specifier controls how the base-class members are accessible in the derived class and
outside it.
Base Member public inheritance protected inheritance private inheritance
public public protected private
protected protected protected private
private not accessible not accessible not accessible
■ Tip
Use 'public' inheritance for 'IS-A' relationships (Dog IS-A Animal). 'private' inheritance means
'implemented-in-terms-of' and is rarely used.
C++ Inheritance Learning Guide • All examples compile with g++ -std=c++17
C++ Inheritance — Complete Guide Page 4
3. Single Inheritance
A derived class inherits from exactly one base class. This is the simplest and most common form.
Example — Animal → Dog
single_inheritance.cpp
#include
#include
using namespace std;
// ■■ Base Class ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
class Animal {
public:
string name;
int age;
Animal(string n, int a) : name(n), age(a) {}
void eat() {
cout << name << " is eating." << endl;
}
void sleep() {
cout << name << " is sleeping." << endl;
}
};
// ■■ Derived Class ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
class Dog : public Animal {
public:
string breed;
Dog(string n, int a, string b)
: Animal(n, a), breed(b) {}
void bark() {
cout << name << " says: Woof!" << endl;
}
void info() {
cout << "Name: " << name
<< ", Breed: " << breed << endl;
}
};
int main() {
Dog d("Bruno", 3, "Labrador");
[Link](); // own method
[Link](); // own method
[Link](); // inherited from Animal
[Link](); // inherited from Animal
return 0;
}
C++ Inheritance Learning Guide • All examples compile with g++ -std=c++17
C++ Inheritance — Complete Guide Page 5
■ Output
Name: Bruno, Breed: Labrador
Bruno says: Woof!
Bruno is eating.
Bruno is sleeping.
C++ Inheritance Learning Guide • All examples compile with g++ -std=c++17
C++ Inheritance — Complete Guide Page 6
4. Multilevel Inheritance
A class inherits from a derived class, forming a chain: Grandparent → Parent → Child.
Animal → Mammal → Dog
[Link]
#include
using namespace std;
class Animal { // Grandparent
public:
void breathe() { cout << "Breathing..." << endl; }
};
class Mammal : public Animal { // Parent
public:
void feedMilk() { cout << "Feeding milk..." << endl; }
};
class Dog : public Mammal { // Child
public:
void bark() { cout << "Woof!" << endl; }
};
int main() {
Dog d;
[Link](); // from Animal (grandparent)
[Link](); // from Mammal (parent)
[Link](); // own method
}
■ Output
Breathing...
Feeding milk...
Woof!
C++ Inheritance Learning Guide • All examples compile with g++ -std=c++17
C++ Inheritance — Complete Guide Page 7
5. Multiple Inheritance
A derived class inherits from two or more base classes simultaneously. Useful when a class
conceptually belongs to multiple categories.
Diamond Problem
When two base classes share a common ancestor, ambiguity arises. Solved using virtual inheritance
(covered in Section 7).
multiple_inheritance.cpp
#include
using namespace std;
class Flyable {
public:
void fly() { cout << "Flying high!" << endl; }
};
class Swimmable {
public:
void swim() { cout << "Swimming fast!" << endl; }
};
// Duck can both fly and swim
class Duck : public Flyable, public Swimmable {
public:
void quack() { cout << "Quack quack!" << endl; }
};
int main() {
Duck duck;
[Link](); // from Flyable
[Link](); // from Swimmable
[Link](); // own
}
■ Output
Flying high!
Swimming fast!
Quack quack!
C++ Inheritance Learning Guide • All examples compile with g++ -std=c++17
C++ Inheritance — Complete Guide Page 8
6. Hierarchical Inheritance
Multiple derived classes inherit from a single base class. Like a tree branching from one root.
Circle Rectangle Triangle
[Link]
#include
#include
using namespace std;
class Shape { // Base
public:
string color;
Shape(string c) : color(c) {}
void showColor() {
cout << "Color: " << color << endl;
}
};
class Circle : public Shape {
public:
double radius;
Circle(string c, double r) : Shape(c), radius(r) {}
void area() {
cout << "Circle area: " << M_PI*radius*radius << endl;
}
};
class Rectangle : public Shape {
public:
double w, h;
Rectangle(string c, double w, double h)
: Shape(c), w(w), h(h) {}
void area() {
cout << "Rectangle area: " << w*h << endl;
}
};
int main() {
Circle c("Red", 5.0);
Rectangle r("Blue", 4.0, 6.0);
[Link](); [Link]();
[Link](); [Link]();
}
C++ Inheritance Learning Guide • All examples compile with g++ -std=c++17
C++ Inheritance — Complete Guide Page 9
■ Output
Color: Red
Circle area: 78.5398
Color: Blue
Rectangle area: 24
C++ Inheritance Learning Guide • All examples compile with g++ -std=c++17
C++ Inheritance — Complete Guide Page 10
7. Hybrid Inheritance & Virtual Base Classes
Hybrid inheritance combines two or more types. The classic problem is the Diamond Problem —
solved with virtual inheritance.
hybrid_virtual.cpp
#include
using namespace std;
class Person { // Grandparent
public:
string name;
Person(string n) : name(n) {}
void show() { cout << "Person: " << name << endl; }
};
// virtual keyword prevents duplicate Person sub-object
class Student : virtual public Person {
public:
Student(string n) : Person(n) {}
void study() { cout << name << " studies." << endl; }
};
class Worker : virtual public Person {
public:
Worker(string n) : Person(n) {}
void work() { cout << name << " works." << endl; }
};
class Intern : public Student, public Worker {
public:
// Intern must initialise the virtual base directly
Intern(string n) : Person(n),
Student(n), Worker(n) {}
};
int main() {
Intern i("Alice");
[Link](); // no ambiguity — only one Person
[Link]();
[Link]();
}
■ Output
Person: Alice
Alice studies.
Alice works.
■ Tip
Without 'virtual', Intern would contain TWO copies of Person, causing ambiguity. Always use virtual
inheritance in diamond hierarchies.
C++ Inheritance Learning Guide • All examples compile with g++ -std=c++17
C++ Inheritance — Complete Guide Page 11
8. Function Overriding
A derived class can redefine a base-class function with the same signature. Use the override
keyword (C++11) to catch typos at compile time.
[Link]
#include
using namespace std;
class Vehicle {
public:
virtual void fuelType() {
cout << "Generic fuel" << endl;
}
void start() {
cout << "Vehicle starting..." << endl;
}
};
class ElectricCar : public Vehicle {
public:
// override keyword ensures signature must match base
void fuelType() override {
cout << "Electric battery" << endl;
}
};
class PetrolCar : public Vehicle {
public:
void fuelType() override {
cout << "Petrol engine" << endl;
}
};
int main() {
Vehicle* v = new Vehicle();
Vehicle* ev = new ElectricCar();
Vehicle* pv = new PetrolCar();
v->fuelType(); // Generic fuel
ev->fuelType(); // Electric battery (runtime dispatch)
pv->fuelType(); // Petrol engine
delete v; delete ev; delete pv;
}
■ Output
Generic fuel
Electric battery
Petrol engine
C++ Inheritance Learning Guide • All examples compile with g++ -std=c++17
C++ Inheritance — Complete Guide Page 12
9. Virtual Functions & Runtime Polymorphism
The virtual keyword enables runtime polymorphism: the correct overridden function is called even
when accessed through a base-class pointer. Always declare destructors virtual in base classes!
[Link]
#include
#include
#include
using namespace std;
class Employee {
public:
string name;
Employee(string n) : name(n) {}
virtual double salary() const = 0; // pure virtual
virtual void display() const {
cout << name << " earns: " << salary() << endl;
}
virtual ~Employee() {} // virtual destructor
};
class Manager : public Employee {
double base, bonus;
public:
Manager(string n, double b, double bo)
: Employee(n), base(b), bonus(bo) {}
double salary() const override { return base + bonus; }
};
class Intern : public Employee {
double stipend;
public:
Intern(string n, double s)
: Employee(n), stipend(s) {}
double salary() const override { return stipend; }
};
int main() {
vector<unique_ptr<Employee>> staff;
staff.push_back(make_unique<Manager>("Priya", 80000, 20000));
staff.push_back(make_unique<Intern>("Raj", 15000));
for (auto const& e : staff)
e->display(); // correct method called at runtime
}
■ Output
Priya earns: 100000
Raj earns: 15000
C++ Inheritance Learning Guide • All examples compile with g++ -std=c++17
C++ Inheritance — Complete Guide Page 13
10. Abstract Classes & Pure Virtual Functions
A class with at least one pure virtual function (= 0) is abstract. You cannot instantiate it directly — it
acts as an interface/contract for derived classes.
abstract_class.cpp
#include
#include
using namespace std;
class Shape { // Abstract class
public:
virtual double area() const = 0; // pure virtual
virtual double perimeter() const = 0; // pure virtual
virtual void draw() const {
cout << "Drawing shape, area=" << area() << endl;
}
virtual ~Shape() {}
};
class Circle : public Shape {
double r;
public:
Circle(double r) : r(r) {}
double area() const override { return M_PI*r*r; }
double perimeter() const override { return 2*M_PI*r; }
};
class Square : public Shape {
double s;
public:
Square(double s) : s(s) {}
double area() const override { return s*s; }
double perimeter() const override { return 4*s; }
};
int main() {
// Shape s; ← compile error: cannot instantiate abstract class
Circle c(5); [Link]();
Square sq(4); [Link]();
cout << "Circle perimeter: " << [Link]() << endl;
cout << "Square perimeter: " << [Link]() << endl;
}
■ Output
Drawing shape, area=78.5398
Drawing shape, area=16
Circle perimeter: 31.4159
Square perimeter: 16
C++ Inheritance Learning Guide • All examples compile with g++ -std=c++17
C++ Inheritance — Complete Guide Page 14
11. Constructors & Destructors in Inheritance
Constructors are called base-first, destructors derived-first. Use the initialiser list to pass arguments
to the base constructor.
[Link]
#include
using namespace std;
class Base {
public:
Base() { cout << "Base constructor" << endl; }
~Base() { cout << "Base destructor" << endl; }
};
class Middle : public Base {
public:
Middle() { cout << "Middle constructor" << endl; }
~Middle() { cout << "Middle destructor" << endl; }
};
class Child : public Middle {
public:
Child() { cout << "Child constructor" << endl; }
~Child() { cout << "Child destructor" << endl; }
};
int main() {
cout << "--- Creating object ---" << endl;
{
Child c; // scoped block forces destructor
}
cout << "--- Object destroyed ---" << endl;
}
Phase Order
Construction Base → Middle → Child
Destruction Child → Middle → Base
C++ Inheritance Learning Guide • All examples compile with g++ -std=c++17
C++ Inheritance — Complete Guide Page 15
12. Common Mistakes & Best Practices
✔ Always declare base class destructorsPrevents
virtual resource leaks when deleting derived objects through a base
✔ Prefer 'override' on every overriding method
The compiler catches signature mismatches that would silently create
✔ Use public inheritance only for IS-A relationships
If it's not truly IS-A, prefer composition over inheritance.
✔ Avoid deep inheritance chains (> 3 levels)
Deep hierarchies are hard to maintain. Flatten with composition or inte
✔ Virtual base classes for diamond hierarchies
Use 'virtual public BaseClass' to avoid duplicate sub-objects.
✔ Do not call virtual functions in constructors/destructors
The vtable is not fully set up yet — the base version is called, not the d
Quick Reference — Inheritance Types
Single: 1 derived ← 1 base | Multilevel: chain A←B←C | Multiple: 1 derived ← 2+ bases | Hierarchical:
many derived ← 1 base | Hybrid: combination (use virtual for diamond)
Happy coding! ■ Master these patterns and C++ inheritance will feel natural.
C++ Inheritance Learning Guide • All examples compile with g++ -std=c++17