Vtable vpointer c++: This article basically gives an idea about how c++ works internally using vTable and vPointer .This will mainly help in clearing the concept of the reader .
The virtual functions are based on the run time binding , so let’s get into depth
The 1st term that comes in the process is binding /linking . It is the linking of the function call with the function definition. Bindings are of two types-
Early binding : Early binding is the default binding method in C++ for all function calls and are assigned by the compiler during compilation.
Dynamic binding : When the member function are made virtual, the compiler binds the function calls to the function definition dynamically. The binding is performed at run time, C++ also adds some data structures to virtual functions i.e.
- vTable
- vPointers
vTable : Every class that contains a virtual function or more has a vTable assigned to it. vTable is a different kind of function pointer array that has the address of all virtual functions of the class. These are built by the compiler during compile time.
vPointer : vPointers are associated with every objects of a class containing a vTable. They are stored in the first 4 bytes of memory. vPointers are used to find the function address during the runtime to do the binding as the virtual functions linking are not done at compile time.
#include <iostream> class convertMessages { int count; public: virtual std::string convert(std::string message) { message = "[Begin]" + message + "[Finish]"; return message; } virtual std::string encrypt(std::string message) { return message; } void aboutInfo() { std::cout << "Convert Messages Class" << std::endl; } }; int main(int argc, char const *argv[]) { convertMessages obj; obj.aboutInfo(); std::cout << obj.encrypt(obj.convert(" works ")); return 0; }
Output : Convert Messages Class [Begin] works [Finish]
In the above example, the class contains virtual functions i.e. encrypt( )
and convert( )
. Hence the class has been assigned a vTable to it.
The steps that happens during a function call in a dynamic binding are-
- The first 4 bytes of the memory taken by the object are used to store vPointer.
- To access the vTable of a class we have to use a vPointer.
- The address of the function from the vTable is fetched
- Finally the function is executed.
Now for inheritance,
#include <iostream> class convertMessages { //Base Class int count; public: virtual std::string convert(std::string message) { message = "[Begin]" + message + "[Finish]"; return message; } virtual std::string encrypt(std::string message) { return message; } void aboutInfo() { std::cout << "Convert Messages Class" << std::endl; } }; //Derived Class class newConvertMessages : public convertMessages { public: std::string convert(std::string message) { message = "[Begin]" + message + "[Finish]"; return message; } }; int main(int argc, char const *argv[]) { newConvertMessages obj; obj.aboutInfo(); std::cout << obj.encrypt(obj.convert(" works ")); return 0; }
Output : Convert Messages Class [Begin] works [Finish]
Once we declare a function as virtual, all the derived class inherited functions are also virtual. In the above example the function newConvertMessages( )
is also virtual even though we did not declare it as a virtual function. So there is also a new vTable created for the function.