Skip to content

Chapter 15 of 31

Polymorphism

Distinguish compile-time overloading from runtime virtual dispatch and avoid slicing.

38 minutes 10 quick checksBy Subha Prasad
Lesson 15 of 31Course navigation

Lesson content

Read, practise, then check your understanding

Polymorphism lets one operation work with different types. Compile-time polymorphism includes function overloading, operator overloading, and templates; the compiler chooses or generates code from static types. Runtime polymorphism uses virtual functions through a base pointer or reference.

#include <iostream>
#include <memory>

struct Shape {
    virtual ~Shape() = default;
    virtual double area() const = 0;
};

struct Square final : Shape {
    double side;
    explicit Square(double value) : side{value} {}
    double area() const override { return side * side; }
};

std::unique_ptr<Shape> shape = std::make_unique<Square>(4.0);
std::cout << shape->area();

override asks the compiler to verify a real override. final can prevent further overriding or derivation. A polymorphic base destructor must be virtual if objects may be deleted through the base.

Slicing and alternatives

Copying a derived object into a base value discards the derived portion, called object slicing. Pass polymorphic objects by reference or pointer and express ownership explicitly. Virtual dispatch has an indirection cost and constrains data layout, but is often appropriate for open runtime families.

Templates provide static dispatch and can inline aggressively, but expose implementation in headers and may increase code size. std::variant is useful for a closed set of alternatives. Choose among virtual interfaces, templates, variants, and ordinary composition based on whether the type set is open, when selection occurs, and what ownership model is required.

Knowledge check

Answer every question correctly to complete this chapter.

Which is compile-time polymorphism?
Which enables runtime polymorphism?
What does override provide?
What is object slicing?
How should polymorphic objects usually be passed?
What is the dynamic type?
What is the static type?
Can constructors dispatch virtually to a further-derived override?
Which cast safely checks a polymorphic downcast?
What alternative provides closed-set value polymorphism?

0 of 10 checks passed

Your progress is saved on this device.