🏛️Go deeper — read the bookObject-Oriented Programming in C++— runnable code & full walkthrough →
oopshigh priority

How Virtual Dispatch Really Works (vtable indexing)

🔑 A virtual call is vptr + a compile-time-fixed slot index: (*obj->vptr[i])(obj). No name lookup.

1 / 8
Each virtual reserves a fixed slot indexVTABLES · read-onlyShape::vtable0x4a10[-1]type_info → Shape[0]area() → Shape::area[1]name() → Shape::nameCircle::vtable0x4a48[-1]type_info → Circle[0]area() → Circle::area[1]name() → Shape::namesShape* objectSOURCE · declaration ordervirtual double area()[0]virtual const char* name()[1]HOW THE CALL LOWERSstdout:
example.cpp
1struct Shape {
2 virtual double area(); // virtual #0 -> vtable slot [0]
3 virtual const char* name(); // virtual #1 -> vtable slot [1]
4 int id; // data member
5};
6struct Circle : Shape {
7 double area() override; // overrides slot [0]
8 double r; // data member
9};
10
11Shape* s = new Circle{}; // vptr set to Circle's vtable
12double a = s->area(); // (*s->vptr[0])(s)

Each virtual reserves a fixed slot index

At compile time the compiler walks Shape's virtual functions in declaration order and reserves a fixed slot: area() -> [0], name() -> [1]. These indices are baked into the binary and never change.

Tap ▶ to play · tap the dots or Next → to step

← Previous
Composition vs Inheritance (IS-A vs HAS-A)
Next →
Abstract Classes, Pure Virtual & Interfaces