面试题答案
一键面试1. 栈展开机制下析构函数调用原理
当C++程序发生异常时,栈展开机制会从异常抛出点开始,按顺序回退栈帧,销毁在异常发生前创建的局部对象。每个局部对象在其作用域结束时,会调用其析构函数。这种机制确保了资源的正确释放,防止内存泄漏等问题。
2. 示例代码
#include <iostream>
class A {
public:
A() { std::cout << "A constructor" << std::endl; }
~A() { std::cout << "A destructor" << std::endl; }
};
class B {
public:
B() { std::cout << "B constructor" << std::endl; }
~B() { std::cout << "B destructor" << std::endl; }
};
class C {
public:
C() { std::cout << "C constructor" << std::endl; }
~C() { std::cout << "C destructor" << std::endl; }
};
void func() {
A a;
B b;
C c;
throw 1;
}
int main() {
try {
func();
} catch (int) {
std::cout << "Caught exception" << std::endl;
}
return 0;
}
3. 代码分析
在上述代码中,func
函数创建了三个对象a
、b
、c
。当throw 1;
语句抛出异常时,栈展开机制开始工作。
- 首先,
c
对象的析构函数被调用,因为它是在栈顶最近创建的对象,输出C destructor
。 - 接着,
b
对象的析构函数被调用,输出B destructor
。 - 最后,
a
对象的析构函数被调用,输出A destructor
。 - 然后
catch
块捕获到异常,输出Caught exception
。
这样通过栈展开机制,在异常发生时,局部对象会按照其创建的相反顺序调用析构函数,确保资源的正确释放。