c++中,当异常遇见构造与析构

来源:互联网 发布:java 队列 线程安全 编辑:程序博客网 时间:2024/06/05 23:39

c++中,当异常遇见构造与析构,会碰撞出什么样的火花?

本来应该说,当构造与析构遇见异常的,但是好像念起来不太顺。就改了下。哈哈。

我们知道资源是有限的,申请资源和释放资源是要配对执行的。有申请无释放,就会造成资源泄露。
废话不多说,先上代码,如下是一个正常的简单代码。先了解一下,之后再进行改造分析。
B类中有一个A类的对象指针。声明下:这个例子中的资源,就是B类中A类指针所指向的内存。
代码的运行结果如下:

1. 构造函数抛异常
1.1. 在B的构造中加异常——未申请资源时抛异常。
执行结果如下:
可以看出,B类构造未完成,但是也没有申请资源,所以并未出现内存泄露。

1.2 在B的构造中加异常——申请资源后抛异常。
执行结果如下:
可以看出,B类构造开始,在A构造完成后,抛也异常,并成功捕获。
但是:此时并没有调用B类的析构函数,也就没有析构已经构造好的A对象,造成构造析构不一致,内存泄露!!!
结论:
1. 构造函数是可以抛异常的。
2. 构造函数中,如果有申请资源,那么在申请资源后抛异常,而没有在构造函数内部进行捕获异常并释放资源,就会造成资源泄露。如上面的内存泄露。
3. 个人理解,构造函数中如果有申请资源的动作,一定不要轻易抛出异常,最好在内部进行异常消化。
不让内部的异常抛外面去。
上面只是以最简单的方式说明,如果完善,可以处理具体异常类型,也可以加RAII机制,如scope_guard之类的处理。

2. 析构函数抛异常
看运行结果,直接就抛外面来了,core掉了!!!捕获异常都没捕获住!!!
查看下core文件,函数调用栈如下:
那就没什么好讲的了,c++的异常处理机制导致的。具体细节逻辑,这里不阐述。
结论:
2 析构函数中产生的异常,抛出后,在析构函数外无法捕获,程序会直接崩溃!
2 定义析构函数时,里面的异常不能往外抛,应该在析构函数中捕获并正确处理。注意这里说的是捕获并正确处理,不是说捕获后就不管了,不管那叫掩盖错误,程序运行下去甚至会有比崩溃更严重的后果。
如下结果运行正常!


原创粉丝点击