In C++, runtime polymorphism is realized using virtual functions. But have you ever wondered how virtual functions work behind the scenes? The C++ language uses Vtable and Vptr to manage virtual functions. In this article, we will understand the concepts of Vtable and Vptr in C++.
Prerequisites: C++ Polymorphism, Inheritance in C++.
What is Polymorphism?
In OOPs, polymorphism refers to the ability of objects to have names but different functionality. The most common use is with base class pointers or references calling derived class functions. This is called runtime polymorphism and is implemented in C++ using virtual functions.
Virtual Functions in C++
A virtual function is a member function that is declared within a base class with the virtual keyword and is re-defined (Overridden) by a derived class. When a class contains a virtual function, it can be overridden in its derived class and tells the compiler to perform dynamic linkage (or late binding) on the function. Now, the virtual functions are implemented in C++ by using vTable and vPtr.
What is vTable?
The vTable, or Virtual Table, is a table of function pointers that is created by the compiler to support dynamic polymorphism. Whenever a class contains a virtual function, the compiler creates a Vtable for that class. Each object of the class is then provided with a hidden pointer to this table, known as Vptr.
The Vtable has one entry for each virtual function accessible by the class. These entries are pointers to the most derived function that the current object should call.
What is vPtr (Virtual Pointer)?
The virtual pointer or _vptr is a hidden pointer that is added by the compiler as a member of the class to point to the VTable of that class. For every object of a class containing virtual functions, a vptr is added to point to the vTable of that class. It's important to note that vptr is created only if a class has or inherits a virtual function.
Understanding vTable and vPtr Using an Example
Here is a simple example with a base class Base and classes Derived1 derived from Base and Derived2 from class Derived1.
C++
// C++ program to show the working of vtable and vptr
#include <iostream>
using namespace std;
// base class
class Base {
public:
virtual void function1()
{
cout << "Base function1()" << endl;
}
virtual void function2()
{
cout << "Base function2()" << endl;
}
virtual void function3()
{
cout << "Base function3()" << endl;
}
};
// class derived from Base
class Derived1 : public Base {
public:
// overriding function1()
void function1()
{
cout << "Derived1 function1()" << endl;
}
// not overriding function2() and function3()
};
// class derived from Derived1
class Derived2 : public Derived1 {
public:
// again overriding function2()
void function2()
{
cout << "Derived2 function2()" << endl;
}
// not overriding function1() and function3()
};
// driver code
int main()
{
// defining base class pointers
Base* ptr1 = new Base();
Base* ptr2 = new Derived1();
Base* ptr3 = new Derived2();
// calling all functions
ptr1->function1();
ptr1->function2();
ptr1->function3();
ptr2->function1();
ptr2->function2();
ptr2->function3();
ptr3->function1();
ptr3->function2();
ptr3->function3();
// deleting objects
delete ptr1;
delete ptr2;
delete ptr3;
return 0;
}
OutputBase function1()
Base function2()
Base function3()
Derived1 function1()
Base function2()
Base function3()
Derived1 function1()
Derived2 function2()
Base function3()
Explanation
1. For Base Class
The base class have 3 virtual function function1(), function2() and function3(). So the vTable of the base class would have 3 elements i.e. function pointer to base::function()
Base Class vTable2. For Derived1 Class
The Derived1 class inherits 3 virtual functions from the Base class but overrides only function1() so all the other functions will be the same as the base class.
Derived1 Class vTable3. For Derived2 Class
The Derived2 class is inherited from Derived1 class so it inherits the function1() of Derived1 and function2() and function3() of Base class. In this class, we have overridden only function2(). So, the vTable for Derived2 class will look like this
Derived2 Class vTable
Similar Reads
shared_ptr in C++
std::shared_ptr is one of the smart pointers introduced in C++11. Unlike a simple pointer, it has an associated control block that keeps track of the reference count for the managed object. This reference count is shared among all the copies of the shared_ptr instances pointing to the same object, e
5 min read
auto_ptr in C++
In C++, a memory leak may occur while de-allocating a pointer. So to ensure that the code is safe from memory leaks and exceptions, a special category of pointers was introduced in C++ which is known as Smart Pointers. In this article, we will discuss the auto pointer(auto_ptr) which is one of the s
4 min read
weak_ptr in C++
The weak_ptr is one of the smart pointers that provide the capability of a pointer with some reduced risks as compared to the raw pointer. The weak_ptr, just like shared_ptr has the capability to point to the resource owned by another shared_ptr but without owning it. In other words, they are able t
3 min read
Pointer to an Array in C++
Pointers in C++ are variables that store the address of another variable while arrays are the data structure that stores the data in contiguous memory locations. In C++, we can manipulate arrays by using pointers to them. These kinds of pointers that point to the arrays are called array pointers or
6 min read
Pointers and References in C++
In C++ pointers and references both are mechanisms used to deal with memory, memory address, and data in a program. Pointers are used to store the memory address of another variable whereas references are used to create an alias for an already existing variable. Pointers in C++ Pointers in C++ are a
5 min read
Unique_ptr in C++
std::unique_ptr is a smart pointer introduced in C++11. It automatically manages the dynamically allocated resources on the heap. Smart pointers are just wrappers around regular old pointers that help you prevent widespread bugs. Namely, forgetting to delete a pointer and causing a memory leak or ac
4 min read
std::vector::assign() in C++ STL
In C++, the vector assign() is a built-in method used to assign the new values to the given vector by replacing old ones. It also modifies the size of the vector according to the given number of elements. Letâs take a look at an example that shows the how to use this function. [GFGTABS] C++ #include
4 min read
stack::push() and stack::pop() in C++ STL
The stack::push() and stack::pop() method in stack container is used to insert and delete the element from the top of stack. They are the member functions of std::stack container defined inside <stack> header file. In this article, we will learn how to use stack::push() and stack::pop() method
2 min read
vector::at() and vector::swap() in C++ STL
In C++, vector at() is a built-in method used to access an element in a vector using index. It is the only access method that performs bound checking before accessing the element to confirm whether the given index lies is within the vector. Letâs take a quick look at a simple example that uses vecto
3 min read
Virtual base class in C++
Virtual base classes are used in virtual inheritance in a way of preventing multiple "instances" of a given class appearing in an inheritance hierarchy when using multiple inheritances. Need for Virtual Base Classes: Consider the situation where we have one class A . This class A is inherited by two
3 min read