Working of Virtual Functions (concept of VTABLE and VPTR)

As discussed here, if a class contains a virtual function then the compiler itself does two things.

  1. If an object of that class is created then a virtual pointer (VPTR) is inserted as a data member of the class to point to the VTABLE of that class. For each new object created, a new virtual pointer is inserted as a data member of that class.
  2. Irrespective of whether the object is created or not, the class contains as a member a static array of function pointers called VTABLE. Cells of this table store the address of each virtual function contained in that class.

Consider the example below:
 

C++




// C++ program to illustrate
// working of Virtual Functions
#include <iostream>
using namespace std;
 
class base {
public:
    void fun_1() { cout << "base-1\n"; }
    virtual void fun_2() { cout << "base-2\n"; }
    virtual void fun_3() { cout << "base-3\n"; }
    virtual void fun_4() { cout << "base-4\n"; }
};
 
class derived : public base {
public:
    void fun_1() { cout << "derived-1\n"; }
    void fun_2() { cout << "derived-2\n"; }
    void fun_4(int x) { cout << "derived-4\n"; }
};
 
int main()
{
    base* p;
    derived obj1;
    p = &obj1;
 
    // Early binding because fun1() is non-virtual
    // in base
    p->fun_1();
 
    // Late binding (RTP)
    p->fun_2();
 
    // Late binding (RTP)
    p->fun_3();
 
    // Late binding (RTP)
    p->fun_4();
 
    // Early binding but this function call is
    // illegal (produces error) because pointer
    // is of base type and function is of
    // derived class
    // p->fun_4(5);
 
    return 0;
}


Output

base-1
derived-2
base-3
base-4

Explanation: Initially, we create a pointer of the type base class and initialize it with the address of the derived class object. When we create an object of the derived class, the compiler creates a pointer as a data member of the class containing the address of VTABLE of the derived class.

A similar concept of Late and Early Binding is used as in the above example. For the fun_1() function call, the base class version of the function is called, fun_2() is overridden in the derived class so the derived class version is called, fun_3() is not overridden in the derived class and is a virtual function so the base class version is called, similarly fun_4() is not overridden so base class version is called.

Note: fun_4(int) in the derived class is different from the virtual function fun_4() in the base class as prototypes of both functions are different.

Virtual Function in C++

A virtual function (also known as virtual methods) is a member function that is declared within a base class and is re-defined (overridden) by a derived class. When you refer to a derived class object using a pointer or a reference to the base class, you can call a virtual function for that object and execute the derived class’s version of the method.

  • Virtual functions ensure that the correct function is called for an object, regardless of the type of reference (or pointer) used for the function call.
  • They are mainly used to achieve Runtime polymorphism.
  • Functions are declared with a virtual keyword in a base class.
  • The resolving of a function call is done at runtime.

Similar Reads

Rules for Virtual Functions

The rules for the virtual functions in C++ are as follows:...

Working of Virtual Functions (concept of VTABLE and VPTR)

...

Limitations of Virtual Functions

As discussed here, if a class contains a virtual function then the compiler itself does two things....

Contact Us