C++对象内存布局--③测试多继承中派生类的虚函数在哪一张虚函数表中
测试2:证明派生类的虚函数的地址跟第一基类的虚函数地址保存在同一张虚函数表中。
派生类有多少个拥有虚函数的基类,派生类对象就有多少个指向虚函数表的指针。
//测试多继承中派生类的虚函数在哪一张虚函数表中.cpp
//2010.8.18
//测试证明派生类的虚函数的地址跟第一基类的虚函数地址保存在同一张虚函数表中。派生类有多少个拥有虚函数的基类,派生类对象就有多少个指向虚函数表的指针。
//VS编译器
#include <iostream>
#include <string>
using namespace std;
//
class Base1
{
public:
Base1(int a1 = 10):a1(a1)
{
cout << "Base1::Base1()" << endl;
}
virtual void show1()
{
cout << "Base1::show1()" << endl;
}
private:
int a1;
};
//
class Base2
{
public:
Base2(int a2 = 20):a2(a2)
{
cout << "Base2::Base2()" << endl;
}
virtual void show2()
{
cout << "Base2::show2()" << endl;
}
private:
int a2;
};
//
class Derived : public Base1, public Base2
{
public:
Derived(int a3 = 100):a3(a3)
{
cout << "Derived::Derived()" << endl;
}
virtual void show3()
{
cout << "Derived::show3()" << endl;
}
private:
int a3;
};
//
int main()
{
Derived aobj;
int** p = (int**)&aobj;
typedef void (__thiscall *fun)(void*pThis);//非常重要
cout << "派生类对象大小 = " << sizeof(aobj) << endl;
cout << "派生类对象内存布局:" << endl;
/*根据输出可以发现:其中成员变量的值分别为0x0A、0x14、0x64,另外的两个为虚函数表指针*/
for (int i = 0; i != sizeof(aobj)/4; ++i)
{
cout << "0x" << p[i] << endl;
}
/*从输出可以证明派生类的虚函数地址跟第一基类的虚函数地址保存在一起*/
cout << "虚函数表指针->虚函数表->函数调用:" << endl;
((fun)(p[0][0]))(p);//Base1::show1()
((fun)(p[0][1]))(p);//Derived::show3()
((fun)(p[2][0]))(p+2);//Base2::show2()
system("pause");
return 0;
}
/*
Base1::Base1()
Base2::Base2()
Derived::Derived()
派生类对象大小 = 20
派生类对象内存布局:
0x0041C254
0x0000000A
0x0041C24C
0x00000014
0x00000064
虚函数表指针->虚函数表->函数调用:
Base1::show1()
Derived::show3()
Base2::show2()
请按任意键继续. . .
*/