Assumption: machine is 32-bit .
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 bint* 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

// 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:
#include <iostream>
using namespace std;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 VPTRcout << "Value at first entry of VIRTUAL TABLE " << (int*)*(int*)*(int*)(&obj+0) << endl;Fun pFun = (Fun)*(int*)*(int*)(&obj+0);   // calling Virtual functionpFun();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 functionscout << "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 functionpFun = (Fun)*((int*)*(int*)(&obj+0)+0);pFun();// calling 2nd virtual functionpFun = (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 Base1pFun = (Fun)*((int*)*(int*)((int*)&obj+0)+0);pFun();// calling 2nd virtual function of Base1pFun = (Fun)*((int*)*(int*)((int*)&obj+0)+1);pFun();// calling 1st virtual function of Base2pFun = (Fun)*((int*)*(int*)((int*)&obj+1)+0);pFun();// calling 2nd virtual function of Base2pFun = (Fun)*((int*)*(int*)((int*)&obj+1)+1);pFun();// calling 1st virtual function of Base3pFun = (Fun)*((int*)*(int*)((int*)&obj+2)+0);pFun();// calling 2nd virtual function of Base3pFun = (Fun)*((int*)*(int*)((int*)&obj+2)+1);pFun();// calling 1st virtual function of DrivepFun = (Fun)*((int*)*(int*)((int*)&obj+0)+2);pFun();// calling 2nd virtual function of DrivepFun = (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