Skip to content

Intermediate · Operator overloading, inheritance and polymorphism · topic 18 of 42 · 25 min

Inheritance: building on an existing class

Explanation

Inheritance lets a new class (derived) reuse and extend an existing class (base). It models an "is-a" relationship: a SavingsAccount is an Account. The derived class gets the base's public and protected members, and its constructor must call a base constructor.

Why inheritance?

Many things share common parts. Every bank account has a number, an owner and a balance, but a savings account also earns interest and a current account allows an overdraft. Instead of copying the common code into each class, you write it once in a base class and let each specific account inherit it. This is inheritance.

Think of it like this: Inheritance is like a family recipe. The base recipe is plain dal. Your mother's version inherits it and adds tadka; your aunt's adds tomatoes. Both are still dal (an "is-a" relationship), and if the base recipe improves, both versions improve.
cpp
#include <iostream>
#include <string>

class Account {
public:
    Account(std::string owner, long long balance)
        : owner_(std::move(owner)), balance_(balance) {}
    void deposit(long long amount) { if (amount > 0) balance_ += amount; }
    long long balance() const { return balance_; }
    const std::string& owner() const { return owner_; }
protected:
    long long balance_;        // derived classes can use this
private:
    std::string owner_;
};

class SavingsAccount : public Account {
public:
    SavingsAccount(std::string owner, long long balance, double rate)
        : Account(std::move(owner), balance), rate_(rate) {}   // call the base constructor
    void addInterest() { balance_ += static_cast<long long>(balance_ * rate_); }
private:
    double rate_;
};

int main() {
    SavingsAccount s("Asha", 100000, 0.04);
    s.deposit(20000);          // inherited from Account
    s.addInterest();           // SavingsAccount's own
    std::cout << s.owner() << ": " << s.balance() << '\n';   // Asha: 124800
}
class SavingsAccount : public Account means "SavingsAccount is an Account". The base part is built first, through the base constructor in the initialiser list.

What the derived class can use

Base member isInside the derived classOutside, through a derived object
publicyesyes (with public inheritance)
protectedyesno
privatenono

Always write public inheritance (class D : public B) unless you have a specific reason. With class D : B (no keyword), inheritance is private by default for classes, which hides the base's public interface and surprises most readers.

Order of construction and destruction

When a derived object is created, the base part is constructed first, then the derived members, then the derived constructor body runs. Destruction happens in exactly the reverse order: derived destructor first, base destructor last. This way the derived class can always rely on its base being ready.

Overriding versus hiding

If the derived class defines a function with the same name as one in the base, the derived version hides the base version when called on a derived object. To change behaviour through a base reference (polymorphism), the base function must be virtual; that is the next topic.

Is-a versus has-a

Use inheritance only for a real "is-a" relationship. A Car HAS an Engine; it is not an Engine. For has-a, put the other class inside as a member: this is composition. A common rule is "prefer composition over inheritance": inheritance ties classes tightly together, and deep hierarchies (five levels of base classes) become hard to change.

cpp
class Engine { public: void start() {} };

class Car {              // composition: Car HAS an Engine
public:
    void start() { engine_.start(); }
private:
    Engine engine_;
};
Composition reuses code without claiming that one thing is another.
Careful: Object slicing: copying a derived object into a base object by value keeps only the base part. Account a = savings; silently drops rate_ and all SavingsAccount behaviour. Pass objects of class hierarchies by reference or pointer, not by value.

Need help?

Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.

Try:

Watch the lesson

Inheritance: building on an existing class · 1/6

Inheritance

Inheritance lets a new class build on an existing one, so common code is written once.

Prefer a video by a teacher? Find free videos on “c++ inheritance public protected base class constructor tutorial” on YouTube ↗

In real life: Employees in a payroll system

A company payroll program has Employee as the base class with name, ID and base salary. Manager inherits from Employee and adds a team size and an allowance. Both are paid by the same payroll code for the common parts, while each class keeps its own extras.

cpp
#include <iostream>
#include <string>

class Employee {
public:
    Employee(std::string name, long long salary) : name_(std::move(name)), salary_(salary) {}
    long long salary() const { return salary_; }
    const std::string& name() const { return name_; }
protected:
    long long salary_;
private:
    std::string name_;
};

class Manager : public Employee {
public:
    Manager(std::string name, long long salary, int team)
        : Employee(std::move(name), salary), team_(team) {}
    long long allowance() const { return 2000LL * team_; }
private:
    int team_;
};

int main() {
    Manager m("Kavya", 90000, 6);
    std::cout << m.name() << " gets " << m.salary() + m.allowance() << '\n';   // Kavya gets 102000
}
Manager reuses everything in Employee and adds only what is new.

Practice (0/4 done)

Task 1 · Question

Which is the correct way to make Dog inherit publicly from Animal?

Task 2 · Question

What is printed? struct B { B() { std::cout << "B"; } ~B() { std::cout << "~B"; } }; struct D : B { D() { std::cout << "D"; } ~D() { std::cout << "~D"; } }; int main() { D d; }

Task 3 · Question

A Library class needs a list of books. What is the best design?

Task 4 · Practice

Create a base class Vehicle (registration number, wheels) and two derived classes, Car and Bike, each adding one member of its own (seats for Car, hasCarrier for Bike). Each derived constructor must call the Vehicle constructor. Print each vehicle's details from main.

Quick quiz

Question 1

1.Which base members can a derived class use directly?

Question 2

2.Which relationship should inheritance model?

Question 3

3.What is object slicing?

Question 4

4.class D : B {}; with class (not struct) and no keyword — what kind of inheritance is it?

Read more (free)

Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.

Which base members can a derived class use directly?

Answer: public and protected

private members stay hidden even from derived classes.

Which relationship should inheritance model?

Answer: is-a

Public inheritance means the derived object can be used wherever the base is expected.

What is object slicing?

Answer: Losing the derived part when a derived object is copied into a base object by value

Only the base sub-object is copied.

class D : B {}; with class (not struct) and no keyword — what kind of inheritance is it?

Answer: private

For class, inheritance is private by default; for struct it is public. Always write public explicitly.

How many base classes can a C# class have?Related

Answer: One

C# has single class inheritance; use interfaces for more abilities.

From Inheritance: base and derived classes

How many classes can a Java class directly extend?Related

Answer: One

Java has single inheritance for classes.

From Inheritance with extends

class B extends A {} (no constructor). What does new B(1, 2) do?Related

Answer: Calls A's constructor with 1, 2

A missing constructor in a subclass passes all arguments to super automatically.

From Inheritance and composition

Can an abstract class have a constructor and data members?Related

Answer: Yes; it just cannot be instantiated on its own

Abstract only means "cannot be created directly". It may still hold shared data and constructors for derived classes.

From Abstract classes, interfaces and good class design

Pass the quiz (60% or more) or mark this topic as done when you are ready.

Your progress is saved on this device only.

Next steps

  1. 2 more topics in “Operator overloading, inheritance and polymorphism” before its exam: Virtual functions and polymorphism, Abstract classes, interfaces and good class design.
  2. Module 5 exam: Operators, inheritance and polymorphism · 13 questions · 25 min, without help. 4 topics of this module still to finish first.
  3. Then the next module, The Standard Template Library (STL). 42 topics left in the course before the final exam.

← Previous: Operator overloading