问题
I have this code:
class Class {
public:
virtual ~Class() {}
};
int main()
{
Class* object = new Class();
delete object;
}
which I compile with Visual C++ 10 and get this disassembly for delete object
statement:
delete object;
test eax,eax
je wmain+23h (401041h)
mov edx,dword ptr [eax]
push 1
mov ecx,eax
call dword ptr [edx]
and this for the actual destructor:
Class::`scalar deleting destructor':
test byte ptr [esp+4],1
push esi
mov esi,ecx
mov dword ptr [esi],offset Class::`vftable' (402100h)
je Class::`scalar deleting destructor'+18h (401018h)
push esi
call dword ptr [__imp_operator delete (4020A8h)]
pop ecx
mov eax,esi
pop esi
ret 4
What is that push 1
doing at the call site and why is the test
at the destructor entry point checking for that value and conditionally bypass call to operator delete()
?
回答1:
The argument is used by the destructor to know if it should call delete at the end.
3 cases where you don't want to call it :
- The destructor is called by a derived class destructor
- The object is allocated on the stack, thus not created with new.
- The object is a field of another object, thus not created by new
EDIT: Add a third case
回答2:
I believe the extra parameter tells the compiler which destructor is the derived-most one, so that it only deallocates memory once, at the appropriate level of inheritance. I've seen something similar in gcc if I recall correctly.
回答3:
Basically, the virtual destructor also implements calling operator delete. The parameter is there to decide whether or not call it.
See this answer that shows the meaning of such hidden destructor parameter.
来源:https://stackoverflow.com/questions/8052146/whats-this-extra-parameter-passed-into-virtual-destructor