C++如何自动调用析构函数?
Posted
技术标签:
【中文标题】C++如何自动调用析构函数?【英文标题】:How does C++ automatically call destructor? 【发布时间】:2018-02-06 23:11:13 【问题描述】:在C++中,我们可以通过对象来管理资源,即在Ctor中获取资源,在Dtor中释放(RAII)。这依赖于 C++ 的自动析构函数调用。但这是如何在幕后完成的呢?例如,C++ 如何知道为c1
而不是c2
调用Dtor。 (我知道这之前一定已经回答过了,但我所有的搜索都以解释如何使用 RAII 的主题结束)。谢谢!
class Cat;
Cat c1;
Cat* c2 = new Cat();
编辑:
我知道我需要为c2
调用删除。我只是不明白当c1
超出范围时如何调用 Dtor。
【问题讨论】:
GCC 是免费软件,Clang 是开源的。去看看吧。 它已经完成,因为 C++ 标准说它必须完成。它是通过让你的 C++ 编译器生成符合 C++ 标准的编译代码来完成的。 编译器将其添加到程序集中。c2
也调用了析构函数,只是不是Cat
析构函数而是Cat*
析构函数,这是微不足道的。
@rozina Calling ~int()
【参考方案1】:
看看compiler explorer。我已经链接了您示例的可构建版本。以防万一链接不是永久性的,如果这个答案,我已经复制了最后的代码。
对于Cat c1;
行(浅红色),您会看到asm 中有三个对应的块,颜色相同。
lea rax, [rbp-28]
mov rdi, rax
call Cat::Cat()
这与堆栈上对象的构造相匹配。
接下来是
lea rax, [rbp-28]
mov rdi, rax
call Cat::~Cat()
这是正常的返回路径,自动调用析构函数。
终于有了
lea rax, [rbp-28]
mov rdi, rax
call Cat::~Cat()
mov rax, rbx
mov rdi, rax
call _Unwind_Resume
这是抛出异常时采用的路径(例如,new
)。它会自动调用析构函数,然后继续异常。
为了完整起见,这里是C++源代码:
class Cat
public:
Cat() : meow()
~Cat()
private:
int meow;
;
void foo()
Cat c1;
Cat* c2 = new Cat();
int main()
foo();
【讨论】:
+1 用于编译器资源管理器。特别是因为您可以轻松地将更复杂的控制流添加到代码中,并查看生成的析构函数调用如何移动。以上是关于C++如何自动调用析构函数?的主要内容,如果未能解决你的问题,请参考以下文章