异常与清理

来源:互联网 发布:财务审批签名软件 编辑:程序博客网 时间:2024/05/16 13:29

下述资源摘自<c++编程思想>

异常处理的魅力之一在于程序能够从正常的处理流程中跳转到恰当的异常处理器中。如果异常抛出时,程序不做恰当的清理工作,那么异常处理本身并没有什么用处。c++的异常处理必须确保当程序的执行流程离开一个作用域的时候,对于属于这个作用域的所有由构造函数建立起来的对象,它们的析构函数一定会被调用。
下面例子演示了当构造函数没有正常结束时不会调用相关联的析构函数。这个例子还显示了当在创建对象数组的过程中抛出异常时会发生什么情况:
#include <iostream>
using namespace std;


class Trace
{
public:
static int counter;
int objid;
Trace()
{
objid = counter++;
cout<<"constructing Trace #"<<objid<<endl;
if(objid==3)
{
throw 3;
}
};
~Trace()
{
cout<<"destructing Trace#"<<objid<<endl;
};
};


int _tmain(int argc, _TCHAR* argv[])
{


try{
Trace obj1;
Trace arr[5];
Trace obj2;
}catch(int i){
cout<<"caught "<<i<<endl;
}


return 0;
}
main函数首先创建一个单独的对象obj1,然后试图创建一个具有5个Trace对象的数组,但是,在#3对象被完整创建之前抛出了一个异常。对象obj2根本就没有被创建。程序的输出结果为:
constructing Trace #0
constructing Trace #1
constructing Trace #2
constructing Trace #3
destructing Trace #2
destructing Trace #1
destructing Trace #0
caught 3
可看到,在异常发生时,c++会调用相应对象的析构函数(我们在析构函数中释放所占用的资源)。但是,如上面所示:如果一个对象的构造函数在执行过程中抛出异常,那么这个对象的析构函数就不会被调用(相应的,已经被占用的内存就没有机会释放)。因此,编写构造函数时,必须特别的仔细。

0 0