Skip to content

Chapter 14 of 31

Inheritance

Use single, multiple, multilevel, hierarchical, and virtual inheritance responsibly.

40 minutes 10 quick checksBy Subha Prasad
Lesson 14 of 31Course navigation

Lesson content

Read, practise, then check your understanding

Inheritance models an is-a relationship. A derived class receives accessible behavior from a base class, then adds or specializes what it needs. Use it when objects genuinely share a common contract—not simply to avoid writing a few lines twice.

Create a base and derived class

#include <iostream>

class Shape {
public:
    virtual double area() const = 0;
    virtual ~Shape() = default;
};

class Rectangle : public Shape {
private:
    double width;
    double height;

public:
    Rectangle(double w, double h) : width(w), height(h) {}

    double area() const override {
        return width * height;
    }
};

Rectangle publicly inherits from Shape. The pure virtual function (= 0) makes Shape an abstract class: it defines a contract but cannot be instantiated directly.

Runtime polymorphism

A base reference or pointer can work with any derived object. The virtual keyword ensures the derived override runs.

void printArea(const Shape& shape) {
    std::cout << shape.area();
}

Rectangle card(4.0, 3.0);
printArea(card); // 12

Add override in the derived class. The compiler will then catch signature mistakes that would otherwise create a different function.

Access levels

  • public members are available to all callers.
  • protected members are available to the class and its derived classes.
  • private members remain inside the declaring class (and its friends).

Prefer private data with protected or public functions. Giving derived classes direct access to state makes invariants harder to protect.

Inheritance shapes

Single inheritance gives one derived class one direct base. Multilevel inheritance extends a chain such as Widget → Button → IconButton. Hierarchical inheritance gives several derived types one base, such as Circle and Rectangle implementing Shape. Multiple inheritance gives a class more than one direct base and works best for small independent interfaces.

struct Printable { virtual void print() const = 0; virtual ~Printable() = default; };
struct Savable { virtual void save() const = 0; virtual ~Savable() = default; };

class Report final : public Printable, public Savable {
public:
    void print() const override { /* render */ }
    void save() const override { /* persist */ }
};

When two inheritance paths contain the same base, the diamond can create duplicate base subobjects. Virtual inheritance (class Left : virtual public Root) makes the most-derived object share one virtual base, but complicates construction and layout. Prefer composition unless shared identity or a true substitutable interface requires inheritance.

Public inheritance models is-a and preserves the base public interface. Protected or private inheritance changes accessibility and is usually less clear than holding a member. Constructors are not automatically inherited unless exposed with using Base::Base; base construction occurs before members and derived construction.

Design guidance

A polymorphic base class should usually have a virtual destructor. This ensures deleting a derived object through a base pointer destroys the complete object safely.

Before choosing inheritance, ask whether composition is clearer: a Car has an Engine, so an engine member is more natural than Car : Engine.

Knowledge check

Answer every question correctly to complete this chapter.

What is the inherited class called?
What relationship should public inheritance model?
What is multiple inheritance?
What solves duplicate virtual-base subobjects in a diamond?
When is composition usually better than inheritance?
What is multilevel inheritance?
What is hierarchical inheritance?
What does protected permit?
Why prefer private base data?
What is the diamond problem?

0 of 10 checks passed

Your progress is saved on this device.