Inheritance and polymorphism
Virtual functions let a base pointer dispatch to the real behaviour of a derived object.
- Declare base-class methods virtual to enable polymorphic dispatch.
- Write override on derived methods so signature mistakes become compile errors.
- Use a pure virtual function to make a class abstract.
- Give any base class used polymorphically a virtual destructor.
In plain English
Inheritance lets one class reuse the interface and behaviour of a base class while specialising it. A virtual function defers the choice of which implementation runs to the actual type of the object, which is called dynamic dispatch. The override keyword documents that a function replaces a virtual one and makes the compiler check the signature for you. An abstract base class declares at least one pure virtual function, so it cannot be instantiated and exists only to define an interface. When you delete a derived object through a base pointer, the base destructor must be virtual so the derived destructor also runs.
Step by step
- 1Define a base class with a pure virtual function to describe the interface.
- 2Declare the base destructor virtual.
- 3Create derived classes that implement the pure virtual function with override.
- 4Store the objects as base-class pointers in a container.
- 5Call the virtual function through the base pointer to see dispatch by real type.
#include <iostream>
#include <memory>
#include <string>
#include <vector>
class Lesson {
public:
virtual ~Lesson() = default;
virtual std::string describe() const = 0;
};
class Video : public Lesson {
public:
std::string describe() const override {
return "video lesson";
}
};
class Quiz : public Lesson {
public:
std::string describe() const override {
return "quiz lesson";
}
};
int main() {
std::vector<std::unique_ptr<Lesson>> lessons;
lessons.push_back(std::make_unique<Video>());
lessons.push_back(std::make_unique<Quiz>());
for (const auto& lesson : lessons) {
std::cout << lesson->describe() << "\n";
}
}Common mistakes
- Deleting a derived object through a non-virtual base destructor is undefined behaviour and can leak or corrupt resources.
- Forgetting the override keyword still compiles but silently fails to override when the signature differs.
- Trying to instantiate an abstract class is a compile error because it has a pure virtual function without an implementation.
- Marking every method virtual is unnecessary; only the methods you intend to override need it.
Make a polymorphic shape
Create an abstract base class Shape with a pure virtual method area() and a virtual destructor. Then create a derived Square that stores a double side and returns side * side from area().
class Shape {
public:
};Why must a base class destructor be virtual when deleting derived objects through a base pointer?
Make it yours.
Keep a private note for this lesson, then turn the key ideas into flashcards you can revisit.
Lock in what you just learned.
Mark this lesson complete to save your place and move one step closer to the certificate.