Vtable vpointer c++ – How virtual functions works internally using vTable and vPointer?

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.