what are vtables

In C++, polymorphism is commonly achieved using virtual functions. But how does the compiler implement this mechanism under the hood? The answer is usually a vtable, or virtual table. This article explains what vtables are, how they work, and why they're important for polymorphism in C++.

What is a VTable?

A vtable is an internal lookup table created by the compiler to support dynamic dispatch of virtual functions. It holds pointers to the virtual functions of a class, allowing the correct function implementation to be called at runtime based on the object's actual type.

In simpler terms, the vtable lets C++ decide which version of a virtual function to call — even when using a pointer or reference to a base class.

Why Do We Need VTables?

Consider this example:

class Base {
public:
  virtual void greet() { std::cout << "Hello from Base\n"; }
};

class Derived : public Base {
public:
  void greet() override { std::cout << "Hello from Derived\n"; }
};

void say_hello(Base* b) {
  b->greet();
}

int main() {
  Derived d;
  say_hello(&d);
  return 0;
}

Without vtables, the call to b->greet() inside say_hello would always invoke Base::greet(), because the pointer type is Base* — the compiler resolves function calls at compile time.

Vtables allow the call to dispatch dynamically at runtime to Derived::greet() because the actual object pointed to is a Derived, not just a Base.

How VTables Work Under the Hood

Although vtable implementation details vary across compilers, the general idea is:

Here’s a rough visualization:

Object memory layout:
+----------------+
| vptr ---------> +---------------------+
+----------------+  | <VTable for Derived>    |
                    +---------------------+
                    | <ptr to Derived::greet>  |
                    | <ptr to other virtual fns> |
                    +---------------------+

Example Walkthrough

For the classes above:

At runtime, when b->greet() is called and b points to a Derived object, the program:

  1. Uses b's vptr to get Derived's vtable.
  2. Looks up the function pointer for greet() in the vtable.
  3. Calls Derived::greet().

Important Notes

Summary

The vtable is the core mechanism behind C++'s support for runtime polymorphism. It allows virtual functions to behave correctly according to the actual object type, enabling powerful and flexible object-oriented designs.

Understanding vtables can help you better grasp how C++ works under the hood and why certain features behave the way they do.


edit this page