接前面虚表的内存分布,今天重点看多重继承的虚表内存分布,简单的说,继承几个类便有几个虚表,如下代码
class Drive : public Base1, public Base2, public Base3 { public: virtual void fd() { cout << "Drive::fd" << endl; } virtual void gd() { cout << "Drive::gd" << endl; } };
则虚表有3个,如下图所示:
添加更多的测试代码:
// trytest.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <WTypes.h> #include < iostream > using namespace std; class Base1 { virtual void f() { cout << "Base1::f" << endl; } virtual void g() { cout << "Base1::g" << endl; } }; class Base2 { virtual void f() { cout << "Base2::f" << endl; } virtual void g() { cout << "Base2::g" << endl; } }; class Base3 { virtual void f() { cout << "Base3::f" << endl; } virtual void g() { cout << "Base3::g" << endl; } }; class Drive : public Base1, public Base2, public Base3 { public: virtual void fd() { cout << "Drive::fd" << endl; } virtual void gd() { cout << "Drive::gd" << endl; } }; typedef void(*Fun)(void); int main() { Drive objDrive; cout << "Size is = " << sizeof(objDrive) << endl; Fun pFun = NULL; cout<<"sizeof(int)="<<sizeof(int)<<endl; cout<<"sizeof(int*)="<<sizeof(int*)<<endl; // 调用Base1的第一个虚函数 pFun = (Fun)*((int*)*(int*)((int*)&objDrive + 0) + 0); pFun(); // 调用Base1的第二个虚函数 pFun = (Fun)*((int*)*(int*)((int*)&objDrive + 0) + 1); pFun(); cout << "Address of virtual pointer 1 " << (int*)(&objDrive + 0) << endl; cout << "Value at virtual pointer i.e. Address of virtual table " << (int*)*(int*)((int*)&objDrive + 0) << endl; cout << "Information about VTable 1" << endl; cout << "Value at 1st entry of VTable " << (int*)*((int*)*(int*)((int*)&objDrive + 0) + 0) << endl; cout << "Value at 2nd entry of VTable " << (int*)*((int*)*(int*)((int*)&objDrive + 0) + 1) << endl; // 调用Base2的第一个虚函数 pFun = (Fun)*((int*)*(int*)((int*)&objDrive + 1) + 0); pFun(); // 调用Base2的第二个虚函数 pFun = (Fun)*((int*)*(int*)((int*)&objDrive + 1) + 1); pFun(); cout << "Address of virtual pointer 2 " << (int*)((int*)&objDrive + 1) << endl; cout << "Value at virtual pointer i.e. Address of virtual table " << (int*)*(int*)((int*)&objDrive + 1) << endl; cout << "Information about VTable 2" << endl; cout << "Value at 1st entry of VTable " << (int*)*((int*)*(int*)((int*)&objDrive + 1) + 0) << endl; cout << "Value at 2nd entry of VTable " << (int*)*((int*)*(int*)((int*)&objDrive + 1) + 1) << endl; // 调用Base3的第一个虚函数 pFun = (Fun)*((int*)*(int*)((int*)&objDrive + 2) + 0); pFun(); // 调用Base3的第二个虚函数 pFun = (Fun)*((int*)*(int*)((int*)&objDrive + 2) + 1); pFun(); cout << "Address of virtual pointer 3 " << (int*)((int*)&objDrive + 2) << endl; cout << "Value at virtual pointer i.e. Address of virtual table " << (int*)*(int*)((int*)&objDrive + 2) << endl; cout << "Information about VTable 3" << endl; cout << "Value at 1st entry of VTable " << (int*)*((int*)*(int*)((int*)&objDrive + 2) + 0) << endl; cout << "Value at 2nd entry of VTable " << (int*)*((int*)*(int*)((int*)&objDrive + 2) + 1) << endl; // 调用派生类的第一个虚函数 pFun = (Fun)*((int*)*(int*)((int*)&objDrive + 0) + 2); pFun(); // 调用派生类的第二个虚函数 pFun = (Fun)*((int*)*(int*)((int*)&objDrive + 0) + 3); pFun(); cout << "Value at 3rd entry of VTable " << (int*)*((int*)*(int*)((int*)&objDrive + 0) + 2) << endl; cout << "Value at 4th entry of VTable " << (int*)*((int*)*(int*)((int*)&objDrive + 0) + 3) << endl; //明确多重继承中虚函数的内存位置 cout <<"Address at 1st entry of VTable " << (int*)*((int*)&objDrive + 0) + 0 << endl; cout <<"Address at 2nd entry of VTable " << (int*)*((int*)&objDrive + 0) + 1 << endl; cout <<"Address at 3rd entry of VTable " << (int*)*((int*)&objDrive + 0) + 2 << endl; cout <<"Address at 4th entry of VTable " << (int*)*((int*)&objDrive + 0) + 3 << endl; pFun = (Fun)*((int*)*((int*)&objDrive + 0) + 0); pFun(); pFun = (Fun)*((int*)*((int*)&objDrive + 0) + 1); pFun(); pFun = (Fun)*((int*)*((int*)&objDrive + 0) + 2); pFun(); pFun = (Fun)*((int*)*((int*)&objDrive + 0) + 3); pFun(); return 0; }
内存分布如下所示: