虚函数的内存结构(二)
一,Class的布局
想要理解虚拟函数的内存布局,需要对class的结构入手,先从struct看起:
struct{
int x,y;
};
如上的结构体在内存中如何存放呢?可以借用《inside the c++ program model》的图形来看该内容:
int x;
int y;
从上图来看在内存中,x,y其实是被分配到一块连续的内存空间中,这块内 存空间的大小是x,y的大小之和(不同的变量类型的话,可能会产生内存对齐的问题,这里不考虑)。
当我们有如下一个class的话:
class point
{
private:
int x,y;
publice:
void first(){};
}
如下声明: point pt;
那么pt 在内存中的存储方式如何呢?事实上它和struct的格式一样。并没有因为它是类而需要更多的信息(如函数名等信息)。而我刚开始的理解不是这样,因为当时没有考虑明白如下的方式中:
point pt;
pt.first();
是如何调用函数的。事实上和在C语言中调用函数没有太多区别。
二,关于虚函数
先来看一段简单的程序:
class point
{
public:
void virtual first();
};
void point::first()
{
return;
}
void main()
{
point pt;
pt.first();
}
反汇编,摘出它的_main函数:
_main:
00401060: 55 push ebp
00401061: 8B EC mov ebp,esp
00401063: 83 EC 44 sub esp,44h
00401066: 53 push ebx
00401067: 56 push esi
00401068: 57 push edi
00401069: 8D 7D BC lea edi,[ebp-44h]
0040106C: B9 11 00 00 00 mov ecx,11h
00401071: B8 CC CC CC CC mov eax,0CCCCCCCCh
00401076: F3 AB rep stos dword ptr [edi]
00401078: 8D 4D FC lea ecx,[ebp-4]
0040107B: E8 85 FF FF FF call @ILT+0(??0point@@QAE@XZ)
00401080: 8D 4D FC lea ecx,[ebp-4]
00401083: E8 87 FF FF FF call @ILT+10(?first@point@@UAEXXZ)
00401088: 5F pop edi
00401089: 5E pop esi
0040108A: 5B pop ebx
0040108B: 83 C4 44 add esp,44h
0040108E: 3B EC cmp ebp,esp
00401090: E8 5B 00 00 00 call __chkesp
00401095: 8B E5 mov esp,ebp
00401097: 5D pop ebp
00401098: C3 ret
00401099: CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC ìììììììììììììììì
004010A9: CC CC CC CC CC CC CC