C++如何自动调用析构函数?

hav*_*vij 5 c++ raii

在C++中,我们可以按对象管理资源,即在Ctor中获取资源,并在Dtor(RAII)中释放它.这依赖于C++的自动析构函数调用.但是如何在引擎盖下完成?例如,C++如何知道调用Dtor c1但不是c2.(我知道之前必须已经回答过,但我的所有搜索都以解释如何使用RAII的主题结束).谢谢!

class Cat;
Cat c1;
Cat* c2 = new Cat();
Run Code Online (Sandbox Code Playgroud)

编辑: 我知道我需要调用删除c2.我只是不明白当Dtor c1超出范围时如何被调用.

Pau*_*oyd 10

看看编译器资源管理器.我已经链接了你的例子的可构建版本.为了防止链接不是永久性的,如果这个答案我已经在最后复制了代码.

对于Cat c1;线条(浅红色),您将看到asm中有三个相应的块,颜色相同.

lea rax, [rbp-28]
mov rdi, rax
call Cat::Cat()
Run Code Online (Sandbox Code Playgroud)

这与堆栈上对象的构造相匹配.

接下来就是

lea rax, [rbp-28]
mov rdi, rax
call Cat::~Cat()
Run Code Online (Sandbox Code Playgroud)

这是正常的返回路径,自动调用析构函数.

终于有了

lea rax, [rbp-28]
mov rdi, rax
call Cat::~Cat()
mov rax, rbx
mov rdi, rax
call _Unwind_Resume
Run Code Online (Sandbox Code Playgroud)

这是抛出异常时所采用的路径(例如,by new).它会自动调用析构函数,然后继续执行异常.

为了完整起见,这里是C++源代码:

class Cat
{
public:
    Cat() : meow() {}
    ~Cat() {}
private:
    int meow;
};

void foo()
{
    Cat c1;
    Cat* c2 = new Cat();
}

int main()
{
    foo();    
}
Run Code Online (Sandbox Code Playgroud)

  • +1 用于编译器资源管理器。特别是因为您可以轻松地向代码添加更复杂的控制流并查看生成的析构函数调用如何移动。 (2认同)