【发布时间】:2012-09-10 10:54:03
【问题描述】:
我有这个代码:
class Class {
public:
virtual void first() {};
virtual void second() {};
};
Class* object = new Class();
object->first();
object->second();
delete object;
我使用 Visual C++ 10 和 /O2 编译并进行了反汇编:
282: Class* object = new Class();
00403953 push 4
00403955 call dword ptr [__imp_operator new (4050BCh)]
0040395B add esp,4
0040395E test eax,eax
00403960 je wmain+1Ch (40396Ch)
00403962 mov dword ptr [eax],offset Class::`vftable' (4056A4h)
00403968 mov esi,eax
0040396A jmp wmain+1Eh (40396Eh)
0040396C xor esi,esi
283: object->first();
0040396E mov eax,dword ptr [esi]
00403970 mov edx,dword ptr [eax]
00403972 mov ecx,esi
00403974 call edx
284: object->second();
00403976 mov eax,dword ptr [esi]
00403978 mov edx,dword ptr [eax+4]
0040397B mov ecx,esi
0040397D call edx
285: delete object;
0040397F push esi
00403980 call dword ptr [__imp_operator delete (405138h)]
请注意,在00403968 处,对象起始地址(存储vptr 的位置)被复制到esi 寄存器中。然后在0040396E,此地址用于检索vptr,vptr 值用于检索first() 的地址。然后在00403976再次检索vptr,用于检索second()的地址。
为什么 vptr 被检索了两次?该对象是否可能在两次调用之间更改其vptr,还是只是优化不足?
【问题讨论】:
-
很奇怪。我认为这一切都应该是无操作的。这可能是优化不足,如果它查看函数内部可能会发现它们都没有改变
esi。
标签: c++ visual-c++ polymorphism rtti virtual-functions