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.