C++ · Chapter 37 of 49

C++ Polymorphism

Polymorphism means 'many forms' — the ability to treat objects of different derived classes through a common base class interface, calling the right overridden method automatically. In C++, runtime polymorphism is achieved using virtual functions and base class pointers/references.

This allows writing generic code that works with any subclass, such as a function that draws any `Shape` without knowing if it's a Circle or Square.

Compile-time vs runtime polymorphism

Function/operator overloading is compile-time polymorphism (resolved at compile time). Virtual functions provide runtime polymorphism, resolved based on the actual object type at runtime.

Using base pointers

A `Shape*` pointing to a `Circle` object will call Circle's overridden draw() method if draw() is virtual, thanks to dynamic dispatch.

Example 1 (cpp)
class Shape {
public:
    virtual void draw() { std::cout << "Shape"; }
};
class Circle : public Shape {
public:
    void draw() override { std::cout << "Circle"; }
};
int main() {
    Shape* s = new Circle();
    s->draw();
    delete s;
}
Output
Circle

Because draw() is virtual, the Circle version runs even through a Shape pointer.

Key points

  • Polymorphism lets one interface represent many object types.
  • Overloading is compile-time polymorphism.
  • Virtual functions enable runtime polymorphism.
  • Base class pointers/references can call overridden derived methods.
💡 Note: Without the virtual keyword, calling a method through a base pointer always calls the base version — this is a common bug.

📝 Quick Quiz

1. Runtime polymorphism in C++ requires:

2. Function overloading is an example of:

3. Without 'virtual', a base pointer calling an overridden method will call: