当某些局部变量超出范围时,会发生堆栈展开。
究竟如何调用析构函数?
我想知道编译器能够通过哪种机制调用堆栈上的对象的析构函数,而不是堆上的对象的析构函数。
答案 0 :(得分:3)
析构函数调用由编译器在生成的代码中发出。
例如,
void foo() {
A a;
}
汇编为:
void foo() {
A::A(<stack-address-of-a>);
A::~A(<stack-address-of-a>);
}
函数早期返回时稍微复杂一些;考虑
void foo(int i) {
A a;
if (i) return;
B b;
}
就像
一样void foo() {
A::A(<stack-address-of-a>);
B::B(<stack-address-of-b>);
if (i) goto destroy_a;
B::~B(<stack-address-of-b>);
destroy_a:
A::~A(<stack-address-of-a>);
}
例外情况再次复杂一些;通常的解决方案涉及将必要的析构函数调用与调用堆栈相关联的异常区域和范围。有关概述,请参阅Exception Handling in LLVM。
答案 1 :(得分:1)
由于它是堆栈(FILO),因此以相反的顺序调用析构函数。因此,最后创建的对象将首先被销毁。
我想知道编译器能够调用的机制 堆栈中对象的析构函数
好吧,如果它把一些东西放到堆栈中,它应该知道如何从堆栈中弹出它,这似乎有意义......调用是在编译过程中添加的。