#include <iostream>
class Base
{
public:
virtual int ShowFunc(int param)
{
std::cout << "Base ShowFunc: " << param << std::endl;
return param;
}
int b;
};
class Derive: public Base
{
public:
int ShowFunc(int param)
{
std::cout << "Derive ShowFunc: " << param << std::endl;
return param;
}
int d;
};
int main()
{
Base b1; 变量地址008bf88c
b1.ShowFunc(1);
Base* b2 = new Derive(); b2变量地址0086f880,保存内容(指针指向)00e51f90
b2->ShowFunc(2);
Derive d1;
d1.ShowFunc(3);
std::cout << sizeof(Base) << " " << sizeof(Derive) << std::endl; // 1个int和1个虚函数表 2个int和1个虚函数表
}
/*
class Derive size(12):
+---
0 | +--- (base class Base)
0 | | {vfptr} 虚函数表,地址为
4 | | b
| +---
8 | d
+---
Derive::$vftable@:
| &Derive_meta
| 0
0 | &Derive::ShowFunc 虚函数表中保存的是子类函数
*/
Base b1;
009E281F lea ecx,[b1]
009E2822 call Base::Base (09E1307h)
b1.ShowFunc(1);
009E2827 push 1
009E2829 lea ecx,[b1]
009E282C call Base::ShowFunc (09E14F1h) 直接调用函数地址
Base* b2 = new Derive();
009E2831 push 0Ch
009E2833 call operator new (09E1140h)
009E2838 add esp,4
009E283B mov dword ptr [ebp-0FCh],eax
009E2841 cmp dword ptr [ebp-0FCh],0
009E2848 je __$EncStackInitStart+71h (09E286Dh)
009E284A xor eax,eax
009E284C mov ecx,dword ptr [ebp-0FCh]
009E2852 mov dword ptr [ecx],eax
009E2854 mov dword ptr [ecx+4],eax
009E2857 mov dword ptr [ecx+8],eax
009E285A mov ecx,dword ptr [ebp-0FCh]
009E2860 call Derive::Derive (09E1221h)
009E2865 mov dword ptr [ebp-104h],eax
009E286B jmp __$EncStackInitStart+7Bh (09E2877h)
009E286D mov dword ptr [ebp-104h],0
009E2877 mov edx,dword ptr [ebp-104h]
009E287D mov dword ptr [b2],edx
b2->ShowFunc(2);
009E2880 mov esi,esp
009E2882 push 2
009E2884 mov eax,dword ptr [b2] eax变为00e51f90,b2变量内容(指针值)
009E2887 mov edx,dword ptr [eax] edx变为009e9c70(虚函数表存储地址),即eax指向内容的第一个字节(00e51f90指向内容第一个字节)
009E2889 mov ecx,dword ptr [b2]
009E288C mov eax,dword ptr [edx] edx(虚函数表存储地址)指向内容的第一个字节,即子类函数showFunc
009E288E call eax 调用虚函数showFunc
009E2890 cmp esi,esp
009E2892 call __RTC_CheckEsp (09E12F3h)
Derive d1;
009E2897 lea ecx,[d1]
009E289A call Derive::Derive (09E1221h)
d1.ShowFunc(3);
009E289F push 3
009E28A1 lea ecx,[d1]
009E28A4 call Derive::ShowFunc (09E14E7h) 直接调用函数地址
![]()