Topic 48 of 91 8. Object-Oriented Programming in C++ Interactive Tutorial

Polymorphism in C++: Compile-Time and Runtime Behavior

9 mins read Last updated: 26 Sep 2026 14,576 views

Direct Answer & Core Concept

Compile-time polymorphism resolves function calls at build time with zero runtime overhead using Function Overloading, Operator Overloading, and Templates. Runtime polymorphism resolves function calls dynamically at runtime using Virtual Functions and vtables, enabling late binding through base class pointers or references.

Detailed Explanation & Mechanics

1. Comparison Matrix:

Architecture Diagram
┌──────────────────────┬───────────────────────────────┬───────────────────────────────┐
│ Feature              │ Static / Compile-Time         │ Dynamic / Runtime             │
├──────────────────────┼───────────────────────────────┼───────────────────────────────┤
│ Mechanism            │ Overloading & Templates       │ Virtual Functions & VTables   │
│ Dispatch Timing      │ Compiler resolves at compile  │ CPU resolves at runtime       │
│ Performance Overhead │ Zero runtime cost (Inlineable)│ VTable pointer lookup indirection│
│ Memory Overhead      │ Slight code bloat (templates) │ 8-byte VPTR per object + VTable│
│ Flexibility          │ Strict type checking at build │ Dynamic plug-and-play plugins │
└──────────────────────┴───────────────────────────────┴───────────────────────────────┘

2. How Runtime Dispatch Works:

Each polymorphic class has a Virtual Method Table (vtable) containing function pointers. Each object stores a virtual table pointer (vptr).

Runnable Code Example: Polymorphism in C++

C++20 / C++23
main.cpp
Run Online
#include <iostream>
#include <vector>
#include <memory>

// 1. Compile-time Polymorphism (Function Overload)
void render(int score) { std::cout << "[Static] Integer score: " << score << "\n"; }
void render(double health) { std::cout << "[Static] Float health: " << health << "%\n"; }

// 2. Runtime Polymorphism (Virtual Hierarchy)
class Shape {
public:
    virtual ~Shape() = default;
    virtual void draw() const = 0; // Dynamic dispatch target
};

class Circle : public Shape {
public:
    void draw() const override { std::cout << "[Dynamic] Drawing Circle (o)\n"; }
};

class Square : public Shape {
public:
    void draw() const override { std::cout << "[Dynamic] Drawing Square [ ]\n"; }
};

int main() {
    // Compile-time resolution
    render(100);
    render(98.5);

    // Runtime dynamic dispatch
    std::vector<std::unique_ptr<Shape>> canvas;
    canvas.push_back(std::make_unique<Circle>());
    canvas.push_back(std::make_unique<Square>());

    for (const auto& s : canvas) {
        s->draw(); // Resolved via vptr -> vtable at runtime
    }
    return 0;
}

Common C++ Technical Interview Questions & Answers

Interview Prep
Q

Q: What is a vtable and where does it reside in memory?

A: A vtable (virtual method table) is an array of function pointers created by the compiler for every class with virtual functions. It usually resides in the read-only data segment (`.rodata`).
Q

Q: What is the memory overhead of virtual functions in an object?

A: Each object contains an extra hidden pointer (`vptr`, usually 8 bytes on 64-bit systems) pointing to its class vtable.

Key Takeaways, Modern Best Practices & Idioms

C++ Best Practices & Production Rules

• Use compile-time polymorphism (templates / concepts) for high-frequency low-latency paths.
• Use runtime polymorphism when collections of heterogeneous types must be managed uniformly.
• Always mark overriding methods with the override keyword to catch signature mismatches at compile time.
We value your privacy & transparency

OperateTools uses cookies and local storage to ensure basic tool functionality, preserve preferences, and analyze aggregated traffic. We never sell your personal data or index your document files. Learn more in our Privacy Policy.