Search⌘ K
AI Features

Inheritance

Explore how inheritance models real-world hierarchies in C++ by allowing base classes to share common logic with derived classes. Understand construction and destruction order, access control using protected members, and the differences between inheritance, composition, and aggregation. This lesson prepares you to design cleaner, more maintainable object-oriented systems using C++ inheritance principles.

We have spent our time defining individual classes. But in the real world, objects are rarely isolated; they belong to hierarchies. A sports car is a car, and a car is a vehicle. If we were to write separate classes for SportsCar, Car, and Vehicle, we would end up copying the same logic for "speed" and "movement" three times. This violates the "Don't Repeat Yourself" (DRY) principle.

In this lesson, we'll use inheritance to write that logic once in a "base" class and share it automatically with "derived" classes. This creates a logical hierarchy that mirrors the real world.

The “is-a” relationship

Inheritance models an "is-a" relationship. When we say Car inherits from Vehicle, we are stating that a Car is a Vehicle.

  • Base class (parent): The class containing general shared logic (e.g., Vehicle).

  • Derived class (child): The class that inherits from the base and adds specific features (e.g., Car ...

Demonstration of “is-a” relationship
Demonstration of “is-a” relationship

Let's look at why we separate these members.

C++ 23
#include <iostream>
#include <string>
// BASE CLASS
class Vehicle {
protected:
// 'protected' allows derived classes (like Car) to access this,
// but keeps it private from the outside world
int speed = 0;
public:
void accelerate(int increase) {
speed += increase;
std::cout << "Vehicle accelerated to " << speed << " mph.\n";
}
};
// DERIVED CLASS
// We use ': public Vehicle' to inherit
class Car : public Vehicle {
public:
int doors = 4; // Specific to Car
void openTrunk() {
// We can access 'speed' here because it is protected in Vehicle
std::cout << "Trunk opened. Car is moving at " << speed << " mph.\n";
}
};
int main() {
Car myCar;
// 1. Inherited behavior
// myCar can call accelerate() even though it's defined in Vehicle
myCar.accelerate(50);
// 2. Specific behavior
// Only Car objects can openTrunk(). A generic Vehicle cannot
myCar.openTrunk();
// 3. Access Control
// myCar.speed = 100; // ERROR: 'speed' is protected, not public
return 0;
}
...