我试图弄清楚使用虚拟析构函数从模块B中删除模块A中创建的对象是否安全。
使用MS C ++编译器时,删除具有虚拟析构函数的对象只会导致单个vtable调用,并且在其中执行基础free()
调用(即在创建对象的同一模块中,即安全) 。
问题是:它只是当前的MS实现,还是在某些标准或文档中得到保证并且可以安全地依赖?
以下是VS2010中反汇编的虚拟析构函数调用的示例:
int _tmain(int argc, _TCHAR* argv[])
{
test *p = new test();
008A1030 push 4
008A1032 call dword ptr [__imp_operator new (8A20A0h)]
008A1038 add esp,4
008A103B test eax,eax
008A103D je wmain+19h (8A1049h)
008A103F mov dword ptr [eax],offset test::`vftable' (8A2100h)
008A1045 mov ecx,eax
008A1047 jmp wmain+1Bh (8A104Bh)
008A1049 xor ecx,ecx
__asm int 3;
008A104B int 3
delete p;
008A104C test ecx,ecx
008A104E je wmain+28h (8A1058h)
008A1050 mov eax,dword ptr [ecx]
008A1052 mov edx,dword ptr [eax]
008A1054 push 1
008A1056 call edx
__asm int 3;
008A1058 int 3
return 0;
008A1059 xor eax,eax
}
答案 0 :(得分:3)
那么,调用者不会知道对象的类型?如果不知道该类型,呼叫者如何呼叫Derived::operator delete
?只有Derived::~Derived
才能知道是否必须调用Derived::operator delete
而不是通用::operator delete
。
因此,我们可以推断出呼叫者无法呼叫::operator delete
。
未指明operator delete
后来是否会调用free()
,但这仍然是一个细节。