liveBook · Manning

Polymorphism

As explained in 100 C++ Mistakes and How to Avoid Them

Polymorphism is the ability to use a common interface while selecting behavior according to an object's actual type.

Polymorphism lets code use a common interface while behavior follows an object's actual type. Inheritance earns its place when classes share a meaningful is-a relationship, not merely a few reusable methods. Reusing unrelated behavior creates awkward names, special-case handling, and objects that cannot substitute for one another. section 7.7

Listing 7.10 A simple inheritance hierarchy
class Person {
    std::string name;
    int age;
};
 
class Student : public Person {
    double gpa;
};

A Person–Student hierarchy shows how a derived object contains base and derived data and can be viewed through either type. section 7.7

Accessing an object through a base reference or pointer exposes the base interface while preserving derived behavior. Storing derived objects as base-class values instead slices away the derived part, so polymorphic collections use pointers or references. A better design gives genuinely different classes a shared interface, such as Moveable, with operations each class implements meaningfully. section 7.7 section 8.8

Listing 7.13 Using an interface-like class
class Moveable {                                             #1
public:
    virtual void move(int) = 0;
    virtual double getPosition() = 0;
};
 
class Square : public Moveable {
private:
    double side;
    double offset;
public:
    Square(double side) : side(side), offset(0) {}
    void move(int n) { this->offset += n*side; }             #2
    double getPosition() { return offset; }
    double area() { return side*side; }
};
 
class Horse : public Moveable {
private:
    double height;
    double position;
public:
    Horse(double height) : height(height), position(0) {}
    void move(int offset) { position += offset; }            #3
    double getPosition() { return position; }
};
 
int main() {
    std::vector<Moveable*> movers;                           #4
    movers.push_back(new Square(1));
    movers.push_back(new Horse(15));
    for (int i = 0; i < movers.size(); ++i) {
        movers[i]->move(2);
        std::cout << "Mover moved " << movers[i]->getPosition() << " units \n";
    }
    return 0;
}

The Moveable example places Square and Horse behind one common interface, allowing one collection and one movement loop without type-specific casts. section 7.7

Treat polymorphic hierarchies as contracts that must remain correct throughout their object lifetimes.

  • Use inheritance for substitutable is-a relationships; separate unrelated classes even when their methods look similar. section 7.7
  • Give a polymorphic base class a virtual destructor when derived objects may be deleted through base pointers; otherwise destruction can leak resources and produce undefined behavior. section 8.8
  • Throw exceptions by value and catch them by reference to avoid pointer-lifetime problems, reduce copying, and preserve overridden behavior. section 10.9
  • Make derived assignment update the base portion as well as derived data; otherwise copying can leave the object's inherited state unchanged. section 8.7

Deleting through a base pointer

A Shape pointer refers to a Square, and area() dispatches correctly. If Shape's destructor is non-virtual, deleting the pointer calls only ~Shape and leaks Square's resource. Making the destructor virtual produces the expected ~Square followed by ~Shape destruction order. section 8.8

How 100 C++ Mistakes and How to Avoid Them covers it

How deep it goes
Explains interfaces, pointers, references, slicing, destruction, exceptions, and assignment, but stops short of broader language mechanics.
Examples
Demonstrates Person and Student, Square and Horse, Moveable collections, Shape destruction, and derived exception handling.
What it assumes
Assumes basic C++ classes and inheritance while teaching polymorphic access, virtual functions, and base-class responsibilities through examples.
What you can do after
Apply it via C++ inheritance and interfaces while avoiding slicing, invalid substitution, unsafe destruction, and incomplete copying.
How it connects
Connects inheritance with virtual functions, object slicing, virtual destructors, exceptions, and copy assignment operators.

Also explained in

Compare how 9 books explain polymorphism →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of 100 C++ Mistakes and How to Avoid Them. The section links point to the parts of the book it draws on.