简体   繁体   English

什么是这个额外的参数传递到虚拟析构函数?

[英]What's this extra parameter passed into virtual destructor?

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: 我使用Visual C ++ 10编译并获取delete object语句的反汇编:

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() ? 什么是push 1在调用站点进行的操作,为什么析构函数入口点的test检查该值并有条件地绕过调用operator delete()

The argument is used by the destructor to know if it should call delete at the end. 析构函数使用该参数来知道它是否应该在结尾调用delete。

3 cases where you don't want to call it : 3个你不想打电话的情况:

  • The destructor is called by a derived class destructor 析构函数由派生类析构函数调用
  • The object is allocated on the stack, thus not created with new. 对象在堆栈上分配,因此不会使用new创建。
  • The object is a field of another object, thus not created by new 该对象是另一个对象的字段,因此不是由new创建的

EDIT: Add a third case 编辑:添加第三个案例

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. 如果我没记错的话,我在gcc中看到了类似的东西。

Basically, the virtual destructor also implements calling operator delete. 基本上,虚拟析构函数还实现了调用操作符delete。 The parameter is there to decide whether or not call it. 该参数用于决定是否调用它。

See this answer that shows the meaning of such hidden destructor parameter . 请参阅此答案,其中显示了此类隐藏析构函数参数的含义

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM