top of page

Virtual function and Internal Implementation.


A virtual function is a member function which is declared within a base class and is re-defined(Overriden) by a derived class.

Virtual function is used to achieve Runtime Polymorphism.

The resolving of function call is done at Run-time.

Rules Behind Virtual Function:

  • Virtual function can not be static.

  • A virtual function can be a friend function of another class.

  • Virtual functions should be accessed using pointer or reference of base class type to achieve run time polymorphism.

  • A class may have virtual destructor but it cannot have a virtual constructor.

What is Virtual Destructor:

Deleting the derived class object using a pointer of base class.

To achieve this feature we use the virtual destuctor.

// Example program


#include<iostream>
  
using namespace std;
  
class base {
  public:
    base()     
    { cout<<"Constructing base \n"; }
    ~base()
    { cout<<"Destructing base \n"; }     
};
  
class derived: public base {
  public:
    derived()     
    { cout<<"Constructing derived \n"; }
    ~derived()
    { cout<<"Destructing derived \n"; }
};
  
int main(void)
{
  base *b = new derived();  
  delete b;
  return 0;
} 

OutPut:

Constructing base

Constructing derived

Destructing base


Here above example derived class object is not deleted so it will cause the memory leak issue so overcome this issue here we will defined the base class destructor as a virtual.


// Example program


#include<iostream>
  
using namespace std;
  
class base {
  public:
    base()     
    { cout<<"Constructing base \n"; }
    virtual ~base()
    { cout<<"Destructing base \n"; }     
};
  
class derived: public base {
  public:
    derived()     
    { cout<<"Constructing derived \n"; }
    ~derived()
    { cout<<"Destructing derived \n"; }
};
  
int main(void)
{
  base *b = new derived();  
  delete b;
  return 0;
}

Output:

Constructing base

Constructing derived

Destructing derived

Destructing base


Internal Implementation of virtual function:

virtual functions is based on run time binding.

Binding/Linking:

Binding is a kind of mapping of a function call with the function’s definition i.e. function’s address.

There are two types of binding:

Early Binding:

By Default C++ Compiler do the early binding for all function calls i.e. while linking when compiler sees a function call, then it binds that call with the particular function’s address / definition.

Dynamic Binding or Run Time Binding:

When we make a member function virtual then compiler performs run time binding for that function i.e. any call to that virtual function will not be linked to any function’s address during compile time. Actual function’s address to this call will be calculated at run time. To resolve the actual function’s address or definition at run time, C++ compiler adds some additional data structure around virtual functions i.e.

  • vTable

  • vPointers

vTable:

Every class that has one or more virtual member functions in it has a vTable associated with it. vTable is a kind of function pointer array that contains the addresses all virtual functions of this class. Compiler builds this vTable at compile time.


vPointer:

Now for every object of a class that has a vTable associated with it, contains a vPointer in first 4 bytes. This vPointer points to the vTable of that class. This vPointer will be used to find the actual function address from vTable at run rime.


// Example program


#include<iostream>
  
using namespace std;
  
class base {
    public:
        virtual void display()//0x1001
        {
            cout<<"In base display"<<endl;
        }
        virtual void show()//0x1002
        {
            cout<<"In base show"<<endl;
        }
};

class derived : public base {
    public:
        void display()//0x1003
        {
            cout<<"In derived class display"<<endl;
        }
};

int main()
{
    base *obj = new derived();
    obj->display();
    obj->show();
    return 0;
}

In above example compiler will create two vTable one for base class and one for derived class.


Here we have created the object for derived class then derived class *vptr pointer will point the derived class virtual table.







Comentários


bottom of page