关于

  • 本文代码演示环境: 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. python 字典 key 对应多个 value

    基本思路是,将key对应的value设置为list,将对应的值append进去. 示例: f=open("a1.txt") ha={} for i in f: i=i.strip( ...

  2. python13各种器

    def hello(): print("hello") def test(): print("test") def hello_wrapper(): print ...

  3. MySQL-数据库多表关联查询太慢,如何进行SQL语句优化

    工作中我们经常用到多个left join去关联其他表查询结果,但是随着数据量的增加,一个表的数据达到百万级别后,这种普通的left join查询将非常的耗时. 举个例子:  现在porder表有 10 ...

  4. 9 — springboot整合jdbc、druid、druid实现日志监控 — 更新完毕

    1.整合jdbc.druid 1).导入依赖 <dependency> <groupId>org.springframework.boot</groupId> &l ...

  5. 日常Java 2021/9/23

    练习使用Math.random函数,以及JOptionPane.showMessageDialog(null,"字符串","Results",JOptionPa ...

  6. A Child's History of England.8

    CHAPTER 3 ENGLAND UNDER THE GOOD SAXON, ALFRED Alfred [born in 849 CE, 唐: 618年-907年] the Great was a ...

  7. day08 文件属性

    day08 系统目录 今日内容 一.重要目录 1./usr 2./var 3./proc 二.文件的属性 1.文件属性的介绍 2.文件属性的详述 3.企业案例 /usr 安装第三方软件的目录: 1./ ...

  8. FileReader (三) - 网页拖拽并预显示图片简单实现

    以下是一个很贱很简单的一个 在网页上图拽图片并预显示的demo. 我是从https://developer.mozilla.org/en-US/docs/Web/API/FileReader#Stat ...

  9. k8s配置中心-configmap,Secret密码

    目录 k8s配置中心-configmap,Secret 创建ConfigMap 使用ConfigMap subPath参数 Secret 官方文档 编写secret清单 使用secret 在 Pod ...

  10. Android实现网络监听

    一.Android Wifi常用广播 网络开发中主体会使用到的action: ConnectivityManager.CONNECTIVITY_ACTION WifiManager.WIFI_STAT ...