>

Monday, 14 December 2015

Virtual Mechanism

How  C++  implements late binding:

The keyword virtual tells the compiler it should not perform early binding. Instead, it should automatically install all the mechanisms necessary to perform late binding.
To accomplish this, the typical compiler1 creates a single table (called the VTABLE) for each class that contains virtual functions.The compiler places the addresses of the virtual functions for that particular class in the VTABLE. In each class with virtual functions,it secretly places a pointer, called the vpointer (abbreviated as VPTR), which points to the VTABLE for that object.
When you make a virtual function call through a base-class pointer the compiler quietly inserts code to fetch the VPTR and look up the function address in the VTABLE, thus calling the correct function and causing late binding to take place.



Virtual:
#include <vector>
#include <string>
#include <iostream>
using namespace std;

class Shape
{
public:
             virtual void draw(){cout<<"Shape draw"<<endl;}
};
class Rectangle:public Shape
{
public:
            void draw(){cout<<"Rectangle draw"<<endl;}
};
class Circle:public Shape
{
public:
            void draw()
            {
            cout<<"Circle draw"<<endl;
            }
};

int _tmain(int argc, _TCHAR* argv[])
{
    vector<Shape *> shapelist;
            Shape *s;
            int choice = 1;
            cout<<"enter 1 for rectangle ,2 for circle,0 for exit"<<endl;
           

            while(choice>0)
            {
                        cin>>choice;
                        if(choice == 1)
                        {
                                    Rectangle R;
                                    s=&R;
                                    shapelist.push_back(s);
                        }
                        else if(choice == 2)
                        {
                                    Circle C;
                                    s=&C;
                                    shapelist.push_back(s);
                        }
                        else
                                    break;
            }
            for(int i =0;i<shapelist.size();i++)
            {
                        shapelist[i]->draw();
            }

            return 0;
}

Run-time polymorphism: Definition: Keeping the behaviour constant and switching the implementation at run-time is called Run-time polymorphism.



Virtual Mechanism:

-   Compiler creates a v-table for each class that has atleast one virtual function.

-   Only one v-table is created for each class irrespective of no of objects.

-   Space cost:  An extra pointer per object + Extra pointer per each virtual method

-   Time cost: Normal function call + Two extra fetches[one to get the value of the v-pointer and a second to get the address of the method]

-   Virtual Function call:
            class Base
{
public:
                        virtual arbitrary_return_type Virt0{..parama..}
                        virtual arbitrary_return_type Virt1{..parama..}
                        virtual arbitrary_return_type Virt2{..parama..}
                        virtual arbitrary_return_type Virt3{..parama..}
                        virtual arbitrary_return_type Virt4{..parama..}
};

Step 1:
The compiler builds a static table containing function pointer for each
Virtual function burying the table into static memory.
V-Table

FunctionPtr Base::__VTable[5] = {&Base::Virt0, &Base::Virt1, &Base::Virt2, &Base::Virt3, &Base::Virt4};


Step 2:
The compiler adds a hidden pointer to each object of the class Base called v-pointer.

Class Base
{
  Public:
    FunctionPtr* __VPTR;
};

Step 3:
The compiler initializes this->__VPTR with in each constructor.The idea is to cause each objects V-Pointer to point to its class’s V-Table.

Base::Base(..params..)
      :__VPTR(&Base::__VTable[0])
{
}

Example:
void MyCode(Base *p)                          void MyCode(Base* p)
{                                              {
                        p->Virt3();        =======>>    p-> __VPTR[3](p);

}                                                          }

0 comments:

Post a Comment