Detail about How VPTR and Virtual table works

Discussion in 'C++' started by asadullah.ansari, Jan 22, 2008.

  1. asadullah.ansari

    asadullah.ansari TechCake

    Joined:
    Jan 9, 2008
    Messages:
    356
    Likes Received:
    14
    Trophy Points:
    0
    Occupation:
    Developer
    Location:
    NOIDA
    Originally written by Zeeshan Amjad

    Assumption: 32-bit Machine.
    Here I am going to explain How Virtual table, Virtual pointer for Virtual functions are internally working.

    First we have understand memory layout.

    Example 1: How the class's memory layout
    Code:
    class Test 
    {
    public:
    	int data1;
    	int data2;
    	int fun1();
    };
    
    int main() 
    {
    	Test obj;
    	cout << "obj's Size = " << sizeof(obj) << endl;
    	cout << "obj 's Address = " << &obj << endl;
    	return 0;
    }
    
    OUTPUT:

    Sobj's Size = 8
    obj 's Address = 0012FF7C

    Note: Any Plane member function does not take any memory.

    Example 2: Memory Layout of Derived class
    Code:
    class Test 
    {
    public:
    	int a;
    	int b;
    };
    
    class dTest : public Test
    {
    public:
    	int c;
    };
    
    int main() 
    {
    	Test obj1;
    	cout << "obj1's Size = " << sizeof(obj1) << endl;
    	cout << "obj1's Address = " << &obj1 << endl;
    	dTest obj2;
    	cout << "obj2's Size = "<< sizeof(obj2) << endl;
    	cout << "obj2's Address = "<< &obj2 << endl;
    	return 0;
    }
    
    OUTPUT:
    obj1's Size = 8
    obj1's Address = 0012FF78
    obj2's Size = 12
    obj2's Address = 0012FF6C

    Example 3: Memory layout If we have one virtual function.
    Code:
    class Test 
    {
    public:
    	int data;
    	virtual void fun1() 
    	{ 
    		cout << "Test::fun1" << endl; 
    	}
    };
    
    int main() 
    {
    	Test obj;
    	cout << "obj's Size = " << sizeof(obj) << endl;
    	cout << "obj's Address = " << &obj << endl;
    	return 0;
    }
    
    OUTPUT:

    obj's Size = 8
    obj's Address = 0012FF7C

    Note: Adding one virtual function in a class takes 4 Byte extra.

    Example 4: More than one Virtual function

    Code:
    class Test 
    {
    public:
    	int data;
    	virtual void fun1() { cout << "Test::fun1" << endl; }
    	virtual void fun2() { cout << "Test::fun2" << endl; }
    	virtual void fun3() { cout << "Test::fun3" << endl; }
    	virtual void fun4() { cout << "Test::fun4" << endl; }
    };
    
    int main()
    {
    	Test obj;
    	cout << "obj's Size = " << sizeof(obj) << endl;
    	cout << "obj's Address = " << &obj << endl;
    	return 0;
    }
    
    OUTPUT:

    obj's Size = 8
    obj's Address = 0012FF7C

    Note: Adding more virtual functions in a class, no extra size taking i.e. Only one machine size taking(i.e. 4 byte)

    Example 5:

    Code:
    class Test
    {
    public:
    	int a;
    	int b;
    	Test(int temp1 = 0, int temp2 = 0)
    	{
    		a=temp1 ;
    		b=temp2 ; 
    	}
    	int getA()  
    	{
    		return a;
    	}
    	int getB()  
    	{
    		return b;
    	}
    	virtual ~Test();
    };
    
    int main() 
    {
    	Test obj(5, 10);
    
    	// Changing a and b
    	int* pInt = (int*)&obj;
    	*(pInt+0) = 100;   
    	*(pInt+1) = 200;   
    
    	cout << "a = " << obj.getA() << endl;
    	cout << "b = " << obj.getB() << endl;
    	return 0;
    }
    
    OUTPUT:
    a = 200
    b = 10

    If we Change the code as then
    Code:
      // Changing a and b
      int* pInt = (int*)&obj;
      *(pInt+1) = 100;   // In place of 0
      *(pInt+2) = 200;   // In place of 1
    
    OUTPUT:
    a = 100
    b = 200

    Note: Who sits 1st place of Class : Answer is VPTR
    VPTR - 1st placed in class and rest sits after it.

    Example 6:

    Code:
    class Test 
    {
    	virtual void fun1() 
    	{
    		cout << "Test::fun1" << endl;
    	}
    };
    
    int main() 
    {
    	Test obj;
    	cout << "VPTR's Address " << (int*)(&obj+0) << endl;
    	cout << "VPTR's Value " << (int*)*(int*)(&obj+0) << endl;
    	return 0;
    }
    
    OUTPUT:

    VPTR's Address 0012FF7C
    VPTR's Value 0046C060

    NOTE: This VPTR's value is a address of Virtual table. Lets see in next Example.

    Example 7:

    Code:
    class Test
    {
    	virtual void fun1() 
    	{ 
    		cout << "Test::fun1" << endl; 
    	}
    };
    typedef void (*Fun)(void);
    
    int main() 
    {
    	Test obj;
    	cout << "VPTR's Address " << (int*)(&obj+0) << endl;
    	cout << " VIRTUAL TABLE 's Address " << (int*)*(int*)(&obj+0) << endl; // Value of VPTR
    	cout << "Value at first entry of VIRTUAL TABLE " << (int*)*(int*)*(int*)(&obj+0) << endl;
    
    	Fun pFun = (Fun)*(int*)*(int*)(&obj+0);   // calling Virtual function
    	pFun();
    	return 0;
    }
    
    OUTPUT:
    VPTR's Address 0012FF7C
    VIRTUAL TABLE 's Address 0046C0EC
    Value at first entry of VIRTUAL TABLE 0040100A
    Test: fun1


    Example 8:

    Code:
    class Test
    {
    	virtual void fun1() { cout << "Test::fun1" << endl; }
    	virtual void func1() { cout << "Test::func1" << endl; }
    };
    
    int main()
    {
    	Test obj;
    
    	cout << "VPTR's Address " << (int*)(&obj+0) << endl;
    	cout << "VIRTUAL TABLE 's Address"<< (int*)*(int*)(&obj+0) << endl;
    
    	// Calling Virtual table functions
    	cout << "Value at 1st entry of VTable " << (int*)*((int*)*(int*)(&obj+0)+0) << endl;
    	cout << "Value at 2nd entry of VTable " << (int*)*((int*)*(int*)(&obj+0)+1) << endl;
    
    	return 0;
    }
    
    
    OUTPUT:

    VPTR's Address 0012FF7C
    VIRTUAL TABLE 's Address 0046C0EC
    Value at first entry of VIRTUAL TABLE 0040100A
    Value at 2nd entry of VIRTUAL TABLE 004012


    Example :9

    Code:
    class Test
    {
    	virtual void fun1() { cout << "Test::fun1" << endl; }
    	virtual void func1() { cout << "Test::func1" << endl; }
    };
    
    typedef void(*Fun)(void);
    
    int main() 
    {
    	Test obj;
    	Fun pFun = NULL;
    
    	// calling 1st virtual function
    	pFun = (Fun)*((int*)*(int*)(&obj+0)+0);
    	pFun();
    
    	// calling 2nd virtual function
    	pFun = (Fun)*((int*)*(int*)(&obj+0)+1);
    	pFun();
    
    	return 0;
    }
    
    OUTPUT:

    Test::fun1
    Test::func1

    Example 10: multiple Inheritance

    Code:
    class Base1 
    {
    public:
    	virtual void fun();
    };
    
    class Base2 
    {
    public:
    	virtual void fun();
    };
    
    class Base3 
    {
    public:
    	virtual void fun();
    };
    
    class Derive : public Base1, public Base2, public Base3 
    {
    };
    
    int main() 
    {
    	Derive obj;
    	cout << "Derive's Size = " << sizeof(obj) << endl;
    	return 0;
    }
    
    OUTPUT:

    Derive's Size = 12


    Example 11: Calling Virtual Functions in case of Multiple Inheritance
    Code:
    class Base1 
    {
    	virtual void fun1() { cout << "Base1::fun1()" << endl; }
    	virtual void func1() { cout << "Base1::func1()" << endl; }
    };
    
    class Base2 {
    	virtual void fun1() { cout << "Base2::fun1()" << endl; }
    	virtual void func1() { cout << "Base2::func1()" << endl; }
    };
    
    class Base3 {
    	virtual void fun1() { cout << "Base3::fun1()" << endl; }
    	virtual void func1() { cout << "Base3::func1()" << endl; }
    };
    
    class Derive : public Base1, public Base2, public Base3 
    {
    public:
    	virtual void Fn() 
    	{ 
    		cout << "Derive::Fn" << endl; 
    	}
    	virtual void Fnc() 
    	{ 
    		cout << "Derive::Fnc" << endl; 
    	}
    };
    
    typedef void(*Fun)(void);
    
    int main()
    {
    	Derive obj;
    	Fun pFun = NULL;
    
    	// calling 1st virtual function of Base1
    	pFun = (Fun)*((int*)*(int*)((int*)&obj+0)+0);
    	pFun();
    
    	// calling 2nd virtual function of Base1
    	pFun = (Fun)*((int*)*(int*)((int*)&obj+0)+1);
    	pFun();
    
    	// calling 1st virtual function of Base2
    	pFun = (Fun)*((int*)*(int*)((int*)&obj+1)+0);
    	pFun();
    
    	// calling 2nd virtual function of Base2
    	pFun = (Fun)*((int*)*(int*)((int*)&obj+1)+1);
    	pFun();
    
    	// calling 1st virtual function of Base3
    	pFun = (Fun)*((int*)*(int*)((int*)&obj+2)+0);
    	pFun();
    
    	// calling 2nd virtual function of Base3
    	pFun = (Fun)*((int*)*(int*)((int*)&obj+2)+1);
    	pFun();
    
    	// calling 1st virtual function of Drive
    	pFun = (Fun)*((int*)*(int*)((int*)&obj+0)+2);
    	pFun();
    
    	// calling 2nd virtual function of Drive
    	pFun = (Fun)*((int*)*(int*)((int*)&obj+0)+3);
    	pFun();
    
    	return 0;
    }
    
    OUTPUT:

    Base1::fun
    Base1::func
    Base2::fun
    Base2::func
    Base3::fun
    Base3::func
    Drive::Fn
    Drive::Fnc
     
  2. shabbir

    shabbir Administrator Staff Member

    Joined:
    Jul 12, 2004
    Messages:
    15,375
    Likes Received:
    388
    Trophy Points:
    83
  3. johnson.reddy

    johnson.reddy New Member

    Joined:
    Feb 5, 2008
    Messages:
    8
    Likes Received:
    0
    Trophy Points:
    0
    I was really confused in virtual functions that how it's internall works. Now I got everything from your post. Thanks
     
  4. mail4aisha

    mail4aisha New Member

    Joined:
    Feb 5, 2008
    Messages:
    2
    Likes Received:
    0
    Trophy Points:
    0
    Thanks Asadullah!!! very explanable and throughly about virtual pointer.
     
  5. flyingfor

    flyingfor New Member

    Joined:
    Feb 6, 2008
    Messages:
    10
    Likes Received:
    0
    Trophy Points:
    0
    Can you take some more complex example of virtual functions like base class' virtual function has default arguments and derived class's virtual function has no default virtual function....
     
  6. alramesh

    alramesh New Member

    Joined:
    Feb 5, 2008
    Messages:
    22
    Likes Received:
    0
    Trophy Points:
    0
    Example 10 is really excellent!!!
     
  7. nileshkumar_1982

    nileshkumar_1982 New Member

    Joined:
    Feb 6, 2008
    Messages:
    11
    Likes Received:
    0
    Trophy Points:
    0
  8. sandymalhotra

    sandymalhotra New Member

    Joined:
    Feb 6, 2008
    Messages:
    9
    Likes Received:
    1
    Trophy Points:
    0
    I am new to C++. As I saw your post I fully understand the concept of VPTR, VTable etc.
    ******** No Issue at all. Thanks **********
     
  9. sydneytech

    sydneytech New Member

    Joined:
    Feb 6, 2008
    Messages:
    12
    Likes Received:
    0
    Trophy Points:
    0
    Really nice info of Virtual function. I was really confused with virtual function having multiple inheritance
     
  10. imrantechi

    imrantechi New Member

    Joined:
    Feb 12, 2008
    Messages:
    116
    Likes Received:
    4
    Trophy Points:
    0
    really this is an excellent article ,there was a lot of confusion in vptr

    this article has really helped me understand the concept better
     
  11. debleena_doll2002

    debleena_doll2002 New Member

    Joined:
    Feb 5, 2008
    Messages:
    119
    Likes Received:
    0
    Trophy Points:
    0
    Really gooood and coooool
     
  12. sydneytech

    sydneytech New Member

    Joined:
    Feb 6, 2008
    Messages:
    12
    Likes Received:
    0
    Trophy Points:
    0
    Can you tell me some virtual function having default parameters and tring overriding derived from base.
     
  13. asadullah.ansari

    asadullah.ansari TechCake

    Joined:
    Jan 9, 2008
    Messages:
    356
    Likes Received:
    14
    Trophy Points:
    0
    Occupation:
    Developer
    Location:
    NOIDA
  14. rashida.par

    rashida.par New Member

    Joined:
    Feb 14, 2008
    Messages:
    21
    Likes Received:
    1
    Trophy Points:
    0
    Nice thing abt VPTR...Thanks
     
  15. shabbir

    shabbir Administrator Staff Member

    Joined:
    Jul 12, 2004
    Messages:
    15,375
    Likes Received:
    388
    Trophy Points:
    83
  16. heena.mca

    heena.mca New Member

    Joined:
    Feb 14, 2008
    Messages:
    20
    Likes Received:
    0
    Trophy Points:
    0
  17. heena.mca

    heena.mca New Member

    Joined:
    Feb 14, 2008
    Messages:
    20
    Likes Received:
    0
    Trophy Points:
    0
    your article is amazing,allthe examples provided is so systematic.
     
  18. heena.mca

    heena.mca New Member

    Joined:
    Feb 14, 2008
    Messages:
    20
    Likes Received:
    0
    Trophy Points:
    0
    this type of articles really help students like us to get a hold on the topic
     
  19. heena.mca

    heena.mca New Member

    Joined:
    Feb 14, 2008
    Messages:
    20
    Likes Received:
    0
    Trophy Points:
    0
    sir if i need any further help ,i would query you.
     
  20. heena.mca

    heena.mca New Member

    Joined:
    Feb 14, 2008
    Messages:
    20
    Likes Received:
    0
    Trophy Points:
    0
    can you please submit some more tough examples
     

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice