A vtable, or virtual table, is a mechanism used by C++ to support dynamic polymorphism through virtual functions.
It is essentially a table of function pointers, with each entry pointing to the most derived implementation of a virtual function that can be called on a given object.
When a class declares or inherits virtual functions, the compiler generates a vtable for that class.
Each instance of the class contains a hidden pointer, often called the vptr (virtual table pointer), that points to the class's vtable.
When a virtual function is called on an object, the program uses the vptr to look up the correct function in the vtable and invokes it.
Here’s a simple example:
#include <iostream>
#include <string>
class Base {
public:
virtual void Speak() {
std::cout << "Base speaking\n";
}
};
class Derived : public Base {
public:
void Speak() override {
std::cout << "Derived speaking\n";
}
};
void CallSpeak(Base& obj) {
obj.Speak();
}
int main() {
Base base;
Derived derived;
CallSpeak(base);
CallSpeak(derived);
}
Base speaking
Derived speaking
In this example:
Base
has a virtual function Speak()
.Derived
overrides Speak()
.As a result, two vtables are created:
Base
has a vtable with an entry pointing to Base::Speak()
.Derived
has its own vtable with an entry pointing to Derived::Speak()
.These vtables are checked when we call class methods:
CallSpeak(base)
is called, the vptr in base
points to the Base
vtable, and Base::Speak()
is invoked.CallSpeak(derived)
is called, the vptr in derived
points to the Derived
vtable, and Derived::Speak()
is invoked.Despite the overhead, vtables are crucial for implementing polymorphism in C++, providing flexibility and enabling powerful design patterns.
Answers to questions are automatically generated and may not have been reviewed.
Learn how to create interfaces and abstract classes using pure virtual functions