How Virtual Function Works Internally in C++ Explained
In C++, a
virtual function works internally using a vtable (virtual table) and a vptr (virtual pointer). Each class with virtual functions has a vtable storing addresses of these functions, and each object has a vptr pointing to its class's vtable, enabling dynamic dispatch at runtime.Syntax
A virtual function is declared by adding the virtual keyword before the function declaration inside a class. This tells the compiler to use dynamic dispatch for this function.
- virtual: Marks the function as virtual.
- return_type: The type of value the function returns.
- function_name(): The function's name and parameters.
Example syntax:
cpp
class Base { public: virtual void show(); };
Example
This example shows how virtual functions enable calling the correct function version based on the actual object type, not the pointer type.
cpp
#include <iostream> using namespace std; class Base { public: virtual void show() { cout << "Base show() called" << endl; } }; class Derived : public Base { public: void show() override { cout << "Derived show() called" << endl; } }; int main() { Base* ptr; Derived d; ptr = &d; ptr->show(); // Calls Derived::show() because show() is virtual return 0; }
Output
Derived show() called
Common Pitfalls
Common mistakes with virtual functions include:
- Forgetting to declare the base class function as
virtual, which disables dynamic dispatch. - Calling virtual functions inside constructors or destructors, which uses the current class's version, not derived overrides.
- Not using
overridekeyword in derived classes, which helps catch mistakes.
cpp
#include <iostream> using namespace std; class Base { public: void show() { // Missing virtual keyword cout << "Base show()" << endl; } }; class Derived : public Base { public: void show() { cout << "Derived show()" << endl; } }; // Usage: // Base* ptr = new Derived(); // ptr->show(); // Calls Base::show(), not Derived::show() because show() is not virtual
Quick Reference
How virtual functions work internally:
- Each class with virtual functions has a
vtablestoring pointers to those functions. - Each object has a hidden
vptrpointing to its class's vtable. - When calling a virtual function, the program uses the
vptrto find the right function address in thevtableand calls it. - This enables runtime polymorphism where the function called depends on the actual object type.
Key Takeaways
Virtual functions use a vtable and vptr to enable dynamic dispatch at runtime.
Declare functions as virtual in the base class to enable polymorphism.
Calling virtual functions in constructors/destructors calls the current class version, not derived overrides.
Use the override keyword in derived classes to avoid mistakes.
Without virtual, function calls are resolved at compile time, not runtime.