1、每个有virtual函数(析构函数或成员函数)的C++类都有一个存放所有虚函数地址的vtable表,每个类的对象都有个指向该类vtable表的vptr指针变量;
2、在vc中,类的继承是在基类后面追加数据的形式进行继承的。
测试代码如下(在64位系统下的vs2013环境中测试的):
//==============================
//@file Polymorphism_eg.cpp
//Polymorphism Programming Exercise
//@author Jaxon Yi <yijianchen@yeah.net>
//20181120
//===============================
#include<iostream>
using namespace std;
//------------------------------------------------------
class Test
{
public:
Test(int a) {data = a;}
//基类中的虚析构函数
virtual ~Test() {cout<<"Test deconstruct"<<endl;}
//基类中的虚函数fun1
virtual void fun1() {cout<<"Test virtual fun1"<<endl;}
//基类中的虚函数fun2
virtual void fun2() {cout<<"Test virtual fun2"<<endl;}
int data;
};
class Test1:public Test
{
public:
Test1(int d1, int d2):Test(d2) {data1 = d1;data2 = d2;}
int data1;
int data2;
//派生类中的虚析构函数
virtual ~Test1() {cout<<"Test1 deconstruct"<<endl;}
//派生类中的虚函数fun11,不是实现基类中的fun1的多态
virtual void fun11() {cout<<"Test1 virtual fun11"<<endl;}
//派生类中的虚函数fun21,不是实现基类中的fun2的多态
virtual void fun21() {cout<<"Test1 virtual fun21"<<endl;}
};
//指向函数的指针
typedef void (*Fun)(void);
int main()
{
cout<<"test in 32bit system"<<endl;
//定义对象子类对象obj
Test1 obj(1,2);
cout << "obj's Size = " << sizeof(obj) << endl;
cout << "obj's Address = " << &obj << endl;
//测试(&obj + 1),(int*)(&obj+1)和*((int*)&obj+1)的区别
cout<<"second Test1 object's address = "<<&obj + 1<<endl;
cout<<"third Test1 object's address = "<<&obj + 2<<endl;
cout<<"first Test1 object-Test1 obj:Base data address and data: "<<(int*)&obj + 1<<"\t"<<*((int*)&obj + 1)<<endl;
cout<<"first Test1 object-Test1 obj:Derivate data1 address and data1:"<<(int*)&obj + 2<<"\t"<<*((int*)&obj + 2)<<endl;
cout<<"first Test1 object-Test1 obj:Derivate data2 address and data2:"<<(int*)&obj + 3<<"\t"<<*((int*)&obj + 3)<<endl;
//获得虚表指针,显示虚表中的内容
cout << "Test1 obj:vptr address = " << (int*)&obj << "\t" << "vptr value(vtable address) = " << *((int*)&obj + 0) << endl;
cout << "vtable value1(first virtual fun address) = " << *((int*)*(int*)((int*)&obj + 0) + 0) << endl;
cout << "vtable value2(second virtual fun address) = " << *((int*)*(int*)((int*)&obj + 0) + 1) << endl;
cout << "vtable value3(third virtual fun address) = " << *((int*)*(int*)((int*)&obj + 0) + 2) << endl;
cout << "vtable value4(forth virtual fun address) = " << *((int*)*(int*)((int*)&obj + 0) + 3) << endl;
cout << "vtable value5(fifth virtual fun address) = " << *((int*)*(int*)((int*)&obj + 0) + 4) << endl;
cout << "vtable value6 = " << *((int*)*(int*)((int*)&obj + 0) + 5) << endl;
cout << "vtable value7 = " << *((int*)*(int*)((int*)&obj + 0) + 6) << endl;
//定义函数指针pFun并赋初值
Fun pFun = NULL;
//调用第二个virtual fun
pFun = (Fun)*((int*)*(int*)((int*)&obj+0)+1);
pFun();
//调用第三个virtual fun
pFun = (Fun)*((int*)*(int*)((int*)&obj+0)+2);
pFun();
//调用第四个virtual fun
pFun = (Fun)*((int*)*(int*)((int*)&obj+0)+3);
pFun();
//调用第五个virtual fun
pFun = (Fun)*((int*)*(int*)((int*)&obj+0)+4);
pFun();
return 0;
}
//=============================================
运行结果如下:
此时子类Test1的vtable表的结构如下:
子类Test1的虚析构函数 | virtual ~Test1() |
---|---|
父类Test的虚成员函数1 | virtual void fun1() |
父类Test的虚成员函数2 | virtual void fun2() |
子类Test1的虚成员函数11 | virtual void fun11() |
子类Test1的虚成员函数21 | virtual void fun21() |
将部分程序修改为:
//基类中的析构函数
~Test() {cout<<"Test deconstruct"<<endl;}
//派生类中的虚析构函数
virtual ~Test1() {cout<<"Test1 deconstruct"<<endl;}
//调用第一个virtual fun
pFun = (Fun)*((int*)*(int*)((int*)&obj+0)+0);
pFun();
//调用第二个virtual fun
pFun = (Fun)*((int*)*(int*)((int*)&obj+0)+1);
pFun();
//调用第四个virtual fun
pFun = (Fun)*((int*)*(int*)((int*)&obj+0)+3);
pFun();
//调用第五个virtual fun
pFun = (Fun)*((int*)*(int*)((int*)&obj+0)+4);
运行结果如下:
此时子类Test1的vtable表的结构如下:
父类Test的虚成员函数1 | virtual void fun1() |
---|---|
父类Test的虚成员函数2 | virtual void fun2() |
子类Test1的虚析构函数 | virtual ~Test1() |
子类Test1的虚成员函数11 | virtual void fun11() |
子类Test1的虚成员函数21 | virtual void fun21() |
将部分程序再次修改为:
//基类中的析构函数
virtual ~Test() {cout<<"Test deconstruct"<<endl;}
//派生类中的虚析构函数
//virtual ~Test1() {cout<<"Test1 deconstruct"<<endl;}
//调用第二个virtual fun
pFun = (Fun)*((int*)*(int*)((int*)&obj+0)+1);
pFun();
//调用第三个virtual fun
pFun = (Fun)*((int*)*(int*)((int*)&obj+0)+2);
pFun();
//调用第四个virtual fun
pFun = (Fun)*((int*)*(int*)((int*)&obj+0)+3);
pFun();
//调用第五个virtual fun
pFun = (Fun)*((int*)*(int*)((int*)&obj+0)+4);
运行结果如下:
此时子类Test1的vtable表的结构如下:
父类Test的虚析构函数 | virtual ~Test() |
---|---|
父类Test的虚成员函数1 | virtual void fun1() |
父类Test的虚成员函数2 | virtual void fun2() |
子类Test1的虚成员函数11 | virtual void fun11() |
子类Test1的虚成员函数21 | virtual void fun21() |