Bytebook Compiler

Inheritance & Polymorphism

Inheritance

Reuse and extend classes: base and derived classes, public/protected/private inheritance, the five types of inheritance, constructor order, and the diamond problem.

6 min read5 runnable examples4-question quiz

Inheritance lets a new class (the derived or child class) take on the members of an existing class (the base or parent class), then add its own or change some. It models an is-a relationship and avoids writing the same code twice.

C++
#include <iostream>
#include <string>
using namespace std;

class Person {                                   // base class
protected:
    string name;
    int age;
public:
    Person(const string &n, int a) : name(n), age(a) {}
    void introduce() const { cout << "I am " << name << ", " << age << " years old." << endl; }
};

class Student : public Person {                  // Student is-a Person
    string course;
public:
    Student(const string &n, int a, const string &c) : Person(n, a), course(c) {}
    void study() const { cout << name << " is studying " << course << "." << endl; }   // can use protected name
};

int main() {
    Student s("Asha", 19, "Data Structures");
    s.introduce();      // inherited from Person
    s.study();          // Student's own
    return 0;
}
Output
I am Asha, 19 years old.
Asha is studying Data Structures.

Access in derived classes

A derived class can use the base's public and protected members, but never its private ones. The mode of inheritance (public, protected, private) then decides how inherited members appear to the outside world:

Base member public inheritance protected inheritance private inheritance
public public protected private
protected protected protected private
private not accessible not accessible not accessible

public inheritance is by far the most common — it is the one that means "is-a".

Types of inheritance

Type Shape Example
Single one base → one derived Car : Vehicle
Multilevel chain: A → B → C Vehicle → Car → ElectricCar
Multiple one class, several bases SmartPhone : Phone, Camera
Hierarchical one base, several derived Shape → Circle, Square, Triangle
Hybrid a mix of the above multiple + multilevel together
ElectricCarCarBikeTruckVehicle
Multilevel (Vehicle → Car → ElectricCar) and hierarchical (Vehicle → Car, Bike, Truck) inheritance in one picture.

Multilevel inheritance and constructor order

Constructors run from the base down to the most derived class; destructors run in the reverse order.

C++
#include <iostream>
using namespace std;

class Vehicle {
public:
    Vehicle()  { cout << "Vehicle constructor" << endl; }
    ~Vehicle() { cout << "Vehicle destructor" << endl; }
};
class Car : public Vehicle {
public:
    Car()  { cout << "  Car constructor" << endl; }
    ~Car() { cout << "  Car destructor" << endl; }
};
class ElectricCar : public Car {
public:
    ElectricCar()  { cout << "    ElectricCar constructor" << endl; }
    ~ElectricCar() { cout << "    ElectricCar destructor" << endl; }
};

int main() {
    ElectricCar tesla;
    cout << "--- object in use ---" << endl;
    return 0;
}
Output
Vehicle constructor
  Car constructor
    ElectricCar constructor
--- object in use ---
    ElectricCar destructor
  Car destructor
Vehicle destructor

Multiple inheritance

C++
#include <iostream>
using namespace std;

class Camera {
public:
    void takePhoto() const { cout << "Click! Photo saved." << endl; }
};
class Phone {
public:
    void call(const char *who) const { cout << "Calling " << who << "..." << endl; }
};
class SmartPhone : public Phone, public Camera {      // two bases
public:
    void browse() const { cout << "Opening browser." << endl; }
};

int main() {
    SmartPhone p;
    p.call("Mom");
    p.takePhoto();
    p.browse();
    return 0;
}
Output
Calling Mom...
Click! Photo saved.
Opening browser.

The diamond problem and virtual base classes

In hybrid inheritance, a class can inherit the same base twice:

PersonStudentEmployeeTA
The diamond: a teaching assistant is both a Student and an Employee, and both are Persons. Arrows point from derived to base.

Without help, TA would contain two copies of Person, and ta.name would be ambiguous. Declaring the shared base virtual makes the derived classes share one copy:

C++
#include <iostream>
#include <string>
using namespace std;

class Person {
public:
    string name;
    Person(const string &n = "") : name(n) { cout << "Person(" << n << ")" << endl; }
};
class Student  : virtual public Person { public: Student()  { cout << "Student" << endl; } };
class Employee : virtual public Person { public: Employee() { cout << "Employee" << endl; } };

class TA : public Student, public Employee {
public:
    TA(const string &n) : Person(n) { cout << "TA" << endl; }   // the most derived class builds the shared base
};

int main() {
    TA ta("Nikhil");
    cout << "name = " << ta.name << " (only one Person inside)" << endl;
    return 0;
}
Output
Person(Nikhil)
Student
Employee
TA
name = Nikhil (only one Person inside)

Overriding (redefining) base functions

A derived class can define a function with the same signature as the base, replacing its behaviour. The base version is still reachable with Base::function():

C++
#include <iostream>
using namespace std;

class Account {
public:
    double interestRate() const { return 3.0; }
};
class SeniorCitizenAccount : public Account {
public:
    double interestRate() const { return Account::interestRate() + 0.5; }   // reuse, then extend
};

int main() {
    Account a;
    SeniorCitizenAccount s;
    cout << "regular: " << a.interestRate() << "%, senior: " << s.interestRate() << "%" << endl;
    return 0;
}
Output
regular: 3%, senior: 3.5%

Without virtual, which version runs depends on the declared type of the pointer or reference — the problem that virtual functions solve.

Test yourself

4 questions · pick an answer to check it instantly

  1. 1

    Can a derived class access its base class's private members directly?

  2. 2

    With class B : protected A, a public member of A becomes...

  3. 3

    Constructing an object of C where C : B and B : A runs constructors in which order?

  4. 4

    What does a virtual base class prevent?