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

时间:2017-08-29 13:09:09

标签: c++ raii

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

class Cat;
Cat c1;
Cat* c2 = new Cat();

修改 我知道我需要为c2调用删除。我只是不明白当c1超出范围时如何调用Dtor。

1 个答案:

答案 0 :(得分:10)

看看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();    
}