c++之别让异常逃离析构函数
关于
- 本文代码演示环境: VS2017.
- 代码写的够不规范,目的是为了缩短文章篇幅.
- 本文主要是为了加深印象,写了好多次的代码,还是忘记了这茬。。。。 之前上传到github的代码会慢慢改过来。
- 本文知识要点来自:《Effective C++》
1.析构函数中出现异常
析构函数中出现异常,异常可能来自自身,也可能是析构其他对象是传下来的。先看个例子
class YYY
{
public:
~YYY()
{
// 自己手动抛出一个异常。用来模拟异常出现在析构函数
throw 1;
}
};
正如注释中说的,析构函数中,手动抛出异常。
代码语法也正确,当执行析构函数时,程序出现了错误,并中止了程序的运行。 程序错误 如下:

图中可以看出,调用函数abort函数(终止了程序)
当使用VS2017编译这份代码时,编译器也给出了警告和提示:
1>XXXXXXX\consoleapplication2.cpp(775): warning C4297: “YYY::~YYY”: 假定函数不引发异常,但确实发生了
1>XXXXXXX\consoleapplication2.cpp(775): note: 析构函数或释放器具有一个(可能是隐含的)非引发异常规范
总结
- 可见,但析构函数出现异常,程序会自动终止。
- 应该避免析构函数出现异常。
2.避免析构函数出现异常。
- 《Effective C++》的意见:析构函数应该吞下不传播异常,或者结束程序,而不是吐出异常;如果要处理异常应该在非析构的普通函数处理
照做
class YYY
{
public:
~YYY()
{
uninit();
}
private:
// 析构前调用
void uninit()
{
try
{
// 自己手动抛出一个异常。
throw 1;
}
// 吞并所有异常。
catch (...)
{
std::cout << "void YYY::uninit() exception\n\n";
}
}
};
- 这里,定义了一个函数Uninit,处理异常。还是手动模拟抛出一个异常。接着,析构函数再调用该函数,这样就将处理异常放在了析构函数之外。
- 运行结果

可见,同样的代码,这次正常运行了。 虽然抛出了异常,但是类YYY将其吞下。避免析构异常调用abort函数终止程序。
最后
Note: 不要让异常逃离析构函数。
c++之别让异常逃离析构函数的更多相关文章
- EC读书笔记系列之4:条款8 别让异常逃离析构函数
条款8 别让异常逃离析构函数 记住: ★析构函数绝对不要吐出异常.若一个被析构函数调用的函数可能抛出异常,析构函数应该捕捉任何异常,然后吞下它们(不传播)或结束程序. ★若客户需对某个操作函数运行期间 ...
- Effective C++ 条款08:别让异常逃离析构函数
1.别让异常逃离析构函数的原因 <Effective C++>第三版中条款08建议不要在析构函数中抛出异常,原因是C++异常机制不能同时处理两个或两个以上的异常.多个异常同时存在的情况下, ...
- Effective C++_笔记_条款08_别让异常逃离析构函数
(整理自Effctive C++,转载请注明.整理者:华科小涛@http://www.cnblogs.com/hust-ghtao/) C++并不禁止析构函数吐出异常,但它不鼓励你这样做.考虑如下代码 ...
- 《Effective C++》——条款08:别让异常逃离析构函数
考虑如下代码: class Widget{ public: ... ~Widget(){...}//假设这个可能吐出一个异常 }; void doSomething() { std::vector&l ...
- Effective C++ 条款八 别让异常逃离析构函数
class DBConn //这个class用来管理DBConnction对象 { public: //自己设计一个新的DBConn接口 方法3 void close() { db.close() ...
- EC笔记,第二部分:8.别让异常逃离析构函数
1.为何析构函数不应该抛出异常? 有两种情况: 1).假设析构函数中有众多语句,而第一条语句抛出异常(或者其他语句),那么抛出异常以后的语句就得不到执行.而通常我们在析构函数中写的是清理资 ...
- Effective C++ -----条款08: 别让异常逃离析构函数
析构函数绝对不要吐出异常.如果一个被析构函数调用的函数可能抛出异常,析构函数应该捕捉任何异常,然后吞下它们(不传播)或结束程序. 如果客户需要对某个操作函数运行期间抛出的异常作出反应,那么class应 ...
- [Effective C++ --008]别让异常逃离析构函数
这章非常容易理解:因为C++并不禁止析构函数吐出异常,只是不鼓励这样做而已. 一.原因 假设我们有10个装着鸡蛋的容器,而且现在我们还想着把它在析构函数打烂. class Egg { public : ...
- NO.7:别让异常逃离析构函数
1.析构函数绝对不要吐出异常,如果一个析构函数可能抛出异常,析构函数应该捕获任何异常,然后要么吞下它们或者退出程序 2.如果用户需要对析构内的可能抛出异常的操作做出反应,则应该将操作放入除析构函数外的 ...
随机推荐
- open 函数小结
umask 掩码 open 函数的时候需要注意,掩码去反之后和设置的值想与,得到真正的值. 可以在命令行 使用umask 来查询 umask 000 设置掩码
- CAS你知道吗
1.比较并交换 CASDemo /** * CAS => compareAndSet * 比较并交换 */ public class CASDemo { public static void m ...
- 【Penetration】红日靶场(一)
nmap探查存活主机 nmap -sP 10.10.2.0/24 图片: https://uploader.shimo.im/f/cfuQ653BEvyA42FR.png!thumbnail?acce ...
- Excel 数据验证:分类选择及输入限制
几个简单设置让你的数据不再出错 如何快速选择某一大类中的细分小类 多级菜单 注意:引用可以创建二级目录,但是引用前应先用公式定义名称,然后引用,引用只能在本sheet操作.
- sax方式解析XML学习笔记
原理:对文档进行顺序扫描,当扫描到文档(document)开始与结束,元素开始与结束.文档结束等地方 通知事件处理函数,由事件处理函数相应动作然后继续同样的扫描,直至文档结束. 优点:消耗资源比较少: ...
- 注解开发中的@Results注解使用
package com.hope.dao;import com.hope.domain.User;import com.sun.xml.internal.bind.v2.model.core.ID;i ...
- 解决tensorflow和keras版本不相匹配的问题
查看安装版本 pip list https://docs.floydhub.com/guides/environments/ 查看对应版本 我感觉是我tensorflow版本装太高了,keras没有
- 莫烦python教程学习笔记——数据预处理之normalization
# View more python learning tutorial on my Youtube and Youku channel!!! # Youtube video tutorial: ht ...
- JDK的简介,卸载和安装过程
JDK的简介,卸载和安装过程 JDK JRE JVM JDK:Java Development Kit JRE:Java Runtime Environment JVM:Java Virtual Ma ...
- 聊聊 SpringBoot 中的两种占位符:@*@ 和 ${*}
前言 在 SpringBoot 项目中,我们经常会使用两种占位符(有时候还会混用),它们分别是: @*@ ${*} 如果我们上网搜索「SpringBoot 的占位符 @」,大部分答案会告诉你,Spri ...