关于

  • 本文代码演示环境: 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++之别让异常逃离析构函数的更多相关文章

  1. EC读书笔记系列之4:条款8 别让异常逃离析构函数

    条款8 别让异常逃离析构函数 记住: ★析构函数绝对不要吐出异常.若一个被析构函数调用的函数可能抛出异常,析构函数应该捕捉任何异常,然后吞下它们(不传播)或结束程序. ★若客户需对某个操作函数运行期间 ...

  2. Effective C++ 条款08:别让异常逃离析构函数

    1.别让异常逃离析构函数的原因 <Effective C++>第三版中条款08建议不要在析构函数中抛出异常,原因是C++异常机制不能同时处理两个或两个以上的异常.多个异常同时存在的情况下, ...

  3. Effective C++_笔记_条款08_别让异常逃离析构函数

    (整理自Effctive C++,转载请注明.整理者:华科小涛@http://www.cnblogs.com/hust-ghtao/) C++并不禁止析构函数吐出异常,但它不鼓励你这样做.考虑如下代码 ...

  4. 《Effective C++》——条款08:别让异常逃离析构函数

    考虑如下代码: class Widget{ public: ... ~Widget(){...}//假设这个可能吐出一个异常 }; void doSomething() { std::vector&l ...

  5. Effective C++ 条款八 别让异常逃离析构函数

    class DBConn //这个class用来管理DBConnction对象 { public:   //自己设计一个新的DBConn接口 方法3 void close() { db.close() ...

  6. EC笔记,第二部分:8.别让异常逃离析构函数

    1.为何析构函数不应该抛出异常?    有两种情况:    1).假设析构函数中有众多语句,而第一条语句抛出异常(或者其他语句),那么抛出异常以后的语句就得不到执行.而通常我们在析构函数中写的是清理资 ...

  7. Effective C++ -----条款08: 别让异常逃离析构函数

    析构函数绝对不要吐出异常.如果一个被析构函数调用的函数可能抛出异常,析构函数应该捕捉任何异常,然后吞下它们(不传播)或结束程序. 如果客户需要对某个操作函数运行期间抛出的异常作出反应,那么class应 ...

  8. [Effective C++ --008]别让异常逃离析构函数

    这章非常容易理解:因为C++并不禁止析构函数吐出异常,只是不鼓励这样做而已. 一.原因 假设我们有10个装着鸡蛋的容器,而且现在我们还想着把它在析构函数打烂. class Egg { public : ...

  9. NO.7:别让异常逃离析构函数

    1.析构函数绝对不要吐出异常,如果一个析构函数可能抛出异常,析构函数应该捕获任何异常,然后要么吞下它们或者退出程序 2.如果用户需要对析构内的可能抛出异常的操作做出反应,则应该将操作放入除析构函数外的 ...

随机推荐

  1. c6和c7

    Centos6.x普遍采用 ext3\ext4(Fourth EXtended filesystem)文件系统格式, EXT3 支持的最大 16TB 文件系统和最大 2TB 文件 Ext4 分别支持1 ...

  2. STM32驱动直流电机的程序与电路设计(IR2110S自举电路+H桥+高级定时器和死区PWM)

    https://blog.csdn.net/geek_monkey/article/details/82079435

  3. mysql-彻底删除方法

    一.如果是使用yum安装的mysql,使用如下命令进行卸载(不能确定使用何种方式安装的mysql情况下,按后续步骤一一进行处理即可): yum remove mysql mysql-server my ...

  4. JavaBean内省与BeanInfo

    Java的BeanInfo在工作中并不怎么用到,我也是在学习spring源码的时候,发现SpringBoot启动时候会设置一个属叫"spring.beaninfo.ignore", ...

  5. 移动开发之h5学习大纲

    移动开发学习形式:授课.自学 1.html5 css3 htm5shiv.js response.js 2.流式布局 自适应布局 盒模型 弹性盒模型 响应式布局3.iscroll swiper boo ...

  6. C++ 成绩排名

    1004 成绩排名 (20分)   读入 n(>)名学生的姓名.学号.成绩,分别输出成绩最高和成绩最低学生的姓名和学号. 输入格式: 每个测试输入包含 1 个测试用例,格式为 第 1 行:正整数 ...

  7. vim使用配置(转)

    在终端下使用vim进行编辑时,默认情况下,编辑的界面上是没有行号的.语法高亮度显示.智能缩进等功能的. 为了更好的在vim下进行工作,需要手动配置一个配置文件: .vimrc 在启动vim时,当前用户 ...

  8. mybatis处理集合、数组参数使用in查询等语句的两种方法

    对于mybatis的参数类型是集合数组的时候进行查询. 第一种:参数list使用mybatis的标签 SELECT * FROM TABLE_NAME AS a <where> <i ...

  9. 莫烦python教程学习笔记——线性回归模型的属性

    #调用查看线性回归的几个属性 # Youtube video tutorial: https://www.youtube.com/channel/UCdyjiB5H8Pu7aDTNVXTTpcg # ...

  10. 十二. Go并发编程--sync/errGroup

    一.序 这一篇算是并发编程的一个补充,起因是当前有个项目,大概の 需求是,根据kafka的分区(partition)数,创建同等数量的 消费者( goroutine)从不同的分区中消费者消费数据,但是 ...