bod*_*ydo 6 c++ resources destructor acquisition
假设我有一个这样的类:
#include <iostream>
using namespace std;
class Boda {
private:
char *ptr;
public:
Boda() {
ptr = new char [20];
}
~Boda() {
cout << "calling ~Boda\n";
delete [] ptr;
}
void ouch() {
throw 99;
}
};
void bad() {
Boda b;
b.ouch();
}
int main() {
bad();
}
Run Code Online (Sandbox Code Playgroud)
似乎析构函数~Boda永远不会被调用,因此ptr资源永远不会被释放.
这是程序的输出:
terminate called after throwing an instance of 'int'
Aborted
Run Code Online (Sandbox Code Playgroud)
所以似乎我的问题的答案是No.
但是当我抛出一个异常时,我认为堆栈被解开了?为什么没有Boda b对象在我的例子中被破坏?
请帮我理解这个资源问题.我想在将来写出更好的程序.
这也就是所谓的RAII?
谢谢,Boda Cydo.
如果异常没有被捕获到任何地方,那么C++运行时可以直接终止程序,而无需进行任何堆栈展开或调用任何析构函数.
但是,如果在调用周围添加try-catch块bad(),您将看到Boda被调用对象的析构函数:
int main() {
try {
bad();
} catch(...) { // Catch any exception, forcing stack unwinding always
return -1;
}
}
Run Code Online (Sandbox Code Playgroud)
RAII意味着动态(堆)分配的内存总是由自动(堆栈)分配的对象拥有,该对象在对象析构时释放它.这依赖于保证在自动分配的对象超出范围时将调用析构函数,无论是由于正常返回还是由于异常.
这种角落情况通常不是RAII的问题,因为通常你想要析构函数运行的主要原因是释放内存,并且当程序终止时,所有内存都会返回给操作系统.但是,如果你的析构函数做了一些更复杂的事情,比如可能删除磁盘上的锁文件或其他东西,那么在崩溃时程序是否会调用析构函数会有所不同,你可能想要将它包装main在一个捕获的try-catch块中所有事情(仅在异常时退出)只是为了确保堆栈在终止之前总是展开.