在多重继承中,子类虚表指针的个数取决于所继承父类的个数,有几个父类就会有几个虚表指针(虚基类除外)。这些指针在将子类对象转换成父类指针时使用,每个虚表指针对应一个父类。
class CSofaBed : public CSofa, public CBed{
public:
CSofaBed(){
00407838 89 4D F0 mov dword ptr [this],ecx
0040783B 8B 4D F0 mov ecx,dword ptr [this]
0040783E E8 3C C8 FF FF call CSofa::CSofa (040407Fh) ;调用第一个父类的构造函数
00407843 C7 45 FC 00 00 00 00 mov dword ptr [ebp-4],0
0040784A 8B 4D F0 mov ecx,dword ptr [this]
0040784D 83 C1 08 add ecx,8 ;将this指针调整到第二个虚函数地址处 这个8是第一个父类的长度
00407850 E8 5C C8 FF FF call CBed::CBed (04040B1h) ;调用第二个父类的构造函数
00407855 8B 45 F0 mov eax,dword ptr [this]
;设置虚表指针
00407858 C7 00 F4 90 49 00 mov dword ptr [eax],offset CSofaBed::`vftable' (04990F4h)
0040785E 8B 45 F0 mov eax,dword ptr [this]
;设置虚表指针
00407861 C7 40 08 34 92 49 00 mov dword ptr [eax+8],offset CSofaBed::`vftable' (0499234h)
子类对象转换为父类指针的特征
CSofaBed SofaBed;
00407BD9 8D 4D E8 lea ecx,[SofaBed]
00407BDC E8 A8 C4 FF FF call CSofaBed::CSofaBed (0404089h)
CSofa *pSofa = &SofaBed;
00407BE1 8D 45 E8 lea eax,[SofaBed]
00407BE4 89 45 E4 mov dword ptr [pSofa],eax ;第一个父类的指针在首地址处
CBed *pBed = &SofaBed;
00407BE7 8D 45 E8 lea eax,[SofaBed]
00407BEA 85 C0 test eax,eax ;检查一下 防止意外
00407BEC 74 0B je main+29h (0407BF9h) ;这里的je和下面的jmp是个不错的特征
00407BEE 8D 4D E8 lea ecx,[SofaBed]
00407BF1 83 C1 08 add ecx,8 ;调整得到第二个父类的指针
00407BF4 89 4D 9C mov dword ptr [ebp-64h],ecx
00407BF7 EB 07 jmp main+30h (0407C00h)
00407BF9 C7 45 9C 00 00 00 00 mov dword ptr [ebp-64h],0
00407C00 8B 55 9C mov edx,dword ptr [ebp-64h]
00407C03 89 55 E0 mov dword ptr [pBed],edx