为什么我的程序集输出中有两个析构函数实现? [英] Why do I have two destructor implementations in my assembly output?
问题描述
和objdump
揭示了我对于同一类有两个不同的析构函数.为什么?
And objdump
of my .o file reveals that I have two different destructors for the same class. Why?
Disassembly of section .text._ZN1AD0Ev:
0000000000000000 <_ZN1AD0Ev>:
0: 53 push %rbx
1: be 00 00 00 00 mov $0x0,%esi
6: 48 89 fb mov %rdi,%rbx
9: 48 c7 07 00 00 00 00 movq $0x0,(%rdi)
10: ba 2c 00 00 00 mov $0x2c,%edx
15: bf 00 00 00 00 mov $0x0,%edi
1a: e8 00 00 00 00 callq 1f <_ZN1AD0Ev+0x1f>
1f: 48 89 df mov %rbx,%rdi
22: be 08 00 00 00 mov $0x8,%esi
27: 5b pop %rbx
28: e9 00 00 00 00 jmpq 2d <_ZN1AD0Ev+0x2d>
Disassembly of section .text._ZN1AD2Ev:
0000000000000000 <_ZN1AD1Ev>:
0: 48 c7 07 00 00 00 00 movq $0x0,(%rdi)
7: ba 2c 00 00 00 mov $0x2c,%edx
c: be 00 00 00 00 mov $0x0,%esi
11: bf 00 00 00 00 mov $0x0,%edi
16: e9 00 00 00 00 jmpq 1b <_ZN1AD1Ev+0x1b>
这些是头文件中的类,这些类导致生成此代码:
These are the classes in the header file that result in this code being generated:
#include <iostream>
class A {
public:
virtual ~A() {
::std::cout << "This destructor does something significant.\n";
}
};
class B : public A {
public:
inline virtual ~B() = 0;
};
B::~B() = default;
class C : public B {
public:
inline virtual ~C() = default;
};
推荐答案
许多编译器会为一个类生成两个不同的析构函数:一个用于销毁动态分配的对象,另一个用于销毁非动态对象(静态对象,本地对象,基本对象).子对象或成员子对象).前者从内部调用operator delete
,后者则不.有些编译器通过向一个析构函数添加一个隐藏参数来做到这一点(旧版本的GCC这样做,MSVC ++这样做),有些编译器仅生成两个单独的析构函数(新版的GCC这样做).
Many compilers generate two different destructors for one class: one for destroying dynamically allocated objects, another - for destroying non-dynamic objects (static objects, local objects, base sub-objects or member sub-objects). The former calls operator delete
from inside, the latter doesn't. Some compilers do it by adding a hidden parameter to one destructor (older versions of GCC do it that way, MSVC++ does it that way), some compilers simply generate two separate destructors (newer versions of GCC do it that way).
从析构函数内部调用operator delete
的需要源于C ++规范,该规范要求应仿佛"选择适当的operator delete
,就像从最派生的析构函数内部(可能是虚拟的)析构函数中查找它一样.目的.因此,可以作为 static 成员函数实现的operator delete
的行为应类似于 virtual 函数.
The need to call operator delete
from inside the destructor arises from C++ specification, which says that the proper operator delete
should be chosen "as if" it was looked up from inside the (possibly virtual) destructor of the most derived object. So, operator delete
, which can be implemented as a static member function should behave as if it were a virtual function.
大多数实现都是从字面上实现此要求的:它们不仅从析构函数内部查找适当的operator delete
,而且实际上从那里调用.
Most implementations implement this requirement "literally": they not only look up the proper operator delete
from inside the destructor, they actually call it from there.
当然,只有从最派生的对象的析构函数中调用operator delete
,并且仅当该对象是动态分配的时才调用.这是隐藏参数(或两个析构函数的版本)进入图片的地方.
Of course, operator delete
only has to be called from the most derived object's destructor, and only if that object was dynamically allocated. This is where that hidden parameter (or two versions of destructor) come into the picture.
这篇关于为什么我的程序集输出中有两个析构函数实现?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!