条款08  别让异常逃离析构函数:

假设在析构函数其中发生了异常,程序可能会过早结束或者导致不明白行为(异常从析构函数传播出去)

看代码:

#include <iostream>
using namespace std; class DBConnection
{
public: void close()
{
int i = 3;
int j = 0;
int k = i/j;
printf("%d\n",k);
}
}; class DBConn
{
public:
DBConn()
{ } /*
~DBConn()
{
db.close();
}
*/ //解决的方法1:强迫结束程序 ~DBConn()
{
try
{
db.close();
}
catch(...)
{
abort();//假设一个程序遭遇一个“于析构期间发生的错误”后无法继续同意,强迫结束是个合理的选择。用abort阻止异常从析构函数传播出去
}
} //解决的方法2:吞下异常
/*
~DBConn()
{
try
{
db.close();
}
catch (...)
{
//制作运转记录,记下对close的调用失败
} }
*/
private:
DBConnection db;
}; int main()
{
DBConn dbc;
//dbc对象销毁时会自己主动调用DBConnection的close函数;仅仅要调用close成功,一切美好,可是假设该调用出现异常。DBConn析构函数
//会传播该异常。也就是同意它离开这个析构函数。 会造成问题。 return 0;
} /* 採用本来的析构函数:
执行程序。提示一个程序已经停止工作(感觉这里编译器优化到解决方式1了,自己主动做了处理),假设不停止工作。也出现了不明白行为。 採用解决方式1:
执行程序,提示一个debug error,终止程序。
採用解决方式2:
执行程序,程序执行通过。可是也不会打印k的值 */

上面的解决方式1和2。都导致对close抛出的异常无法处理:

最佳办法就是DBConn自己又一次设计一个close接口,使得程序猿能够自己调用:

#include <iostream>
using namespace std; class DBConnection
{
public: void close()
{
int i = 3;
int j = 0;
int k = i/j;
printf("%d\n",k);
}
}; class DBConn
{
public:
DBConn()
{ }
~DBConn()
{
if (!closed)
{
try //关闭连接。假设客户不那么做的话
{
db.close()
}
catch(...)
{
//在这里结束程序或者吞下异常
}
} } void close()
{
db.close();
closed = true;
} private:
DBConnection db;
bool closed;
}; int main()
{
DBConn dbc;
//dbc对象销毁时会自己主动调用DBConnection的close函数;仅仅要调用close成功,一切美好,可是假设该调用出现异常,DBConn析构函数
//会传播该异常,也就是同意它离开这个析构函数。会造成问题。 return 0;
} /* 这种方法把调用close的责任从DBConn析构函数手上移动到DBConn客户手上(但DBConn析构函数仍含有一个“双保险”调用). 假设某个操作可能在失败时抛出异常。而又存在某种须要必须处理该异常,那么这个异常必须来自析构函数以外的某个函数
由于析构函数吐出异常,总会带来“过早结束程序”或者“发生不明白行为”的风险。 这里由客户自己调用close函数。假设发现异常,能够处理。 总结: 1:析构函数绝对不要吐出异常,假设一个被析构函数调用的函数可能抛出异常,析构函数应该捕捉该异常,然后吞下它们(不传播)或结束程序
2:假设客户须要对某个操作函数执行期间抛出的异常做出反应,那么class应该提供一个普通函数(而非析构函数)执行该操作。 */

1:析构函数绝对不要吐出异常。假设一个被析构函数调用的函数可能抛出异常,析构函数应该捕捉该异常。然后吞下它们(不传播)或结束程序

2:假设客户须要对某个操作函数执行期间抛出的异常做出反应,那么class应该提供一个普通函数(而非析构函数)执行该操作。

effective C++ 读书笔记 条款08的更多相关文章

  1. effective C++ 读书笔记 条款11

    条款11: 在operator= 中处理"自我赋值" 在实现operator=时考虑自我赋值是必要的就像 x=y .我们不知道变量x与y代表的值是否为同一个值(把x和y说成是一个指 ...

  2. effective C++ 读书笔记 条款14 以对象管理资源

    如果我们使用一个投资行为的程序库: #include "stdafx.h" #include <iostream> #include <memory> us ...

  3. Effective STL 读书笔记

    Effective STL 读书笔记 标签(空格分隔): 未分类 慎重选择容器类型 标准STL序列容器: vector.string.deque和list(双向列表). 标准STL管理容器: set. ...

  4. Effective STL读书笔记

    Effective STL 读书笔记 本篇文字用于总结在阅读<Effective STL>时的笔记心得,只记录书上描写的,但自己尚未熟练掌握的知识点,不记录通用.常识类的知识点. STL按 ...

  5. 《Effective C++》读书笔记 条款02 尽量以const,enum,inline替换#define

    Effective C++在此条款中总结出两个结论 1.对于单纯常量,最好以const对象或enum替换#define 2.对于形似函数的宏,最好改用inline函数替换#define 接下来我们进行 ...

  6. effective c++读书笔记(一)

    很早之前就听过这本书,找工作之前读一读.看了几页,个人感觉实在是生涩难懂,非常不符合中国人的思维方式.之前也有博主做过笔记,我来补充一些自己的理解. 我看有人记了笔记,还不错:http://www.3 ...

  7. Effective Java读书笔记完结啦

    Effective Java是一本经典的书, 很实用的Java进阶读物, 提供了各个方面的best practices. 最近终于做完了Effective Java的读书笔记, 发布出来与大家共享. ...

  8. Effective C++读书笔记(转)

    第一部分 让自己习惯C++ 条款01:视C++为一个语言联邦 一.要点 ■ c++高效编程守则视状况而变化,取决于你使用c++的哪一部分. 二.扩展 将c++视为一个由相关语言组成的联邦而非单一语言会 ...

  9. 【Effective C++ 读书笔记】条款02: 尽量以 const, enum, inline 替换 #define

    条款02: 尽量以 const, enum, inline 替换 #define 这个条款或许可以改为“宁可以编译器替换预处理器”. 编译过程: .c文件--预处理-->.i文件--编译--&g ...

随机推荐

  1. golang container heap&sort

    go语言也自己的容器数据结构.主要有list.heap和ring package main import ( "container/heap" "fmt" &q ...

  2. Mysql字符集介绍

  3. python中的*号

    from:https://www.douban.com/note/231603832/ 传递实参和定义形参(所谓实参就是调用函数时传入的参数,形参则是定义函数是定义的参数)的时候,你还可以使用两个特殊 ...

  4. Android 4.4 API

    Android 4.4 (KITKAT) 是新的 Android 平台版本,为用户和应用开发者提供了新功能.本文旨在介绍其中最值得关注的新 API. 作为应用开发者,您应尽快从 SDK 管理器下载 A ...

  5. ssh隐藏的sftp功能的使用

    sftp是Secure File Transfer Protocol的缩写,安全文件传送协议.可以为传输文件提供一种安全的加密方法.sftp 与 ftp 有着几乎一样的语法和功能.SFTP 为 SSH ...

  6. ElastAlert告警

    ElastAlert告警 https://blog.csdn.net/qq_38369069/article/details/80842432

  7. 003 RequestMapping——Ant路径

    一: 1.介绍 Ant风格资源地址支持3中配配符 ?:匹配文件名中的一个字符 *  :匹配文件名中的任意字符 **:匹配多层路径 2.RequestMapping支持的Ant风格的路径 二:程序说明 ...

  8. 006.Zabbix添加监控主机

    一 配置步骤和流程 Zabbix完整的监控配置流程可以简单的描述为: Host groups(主机组)---->Hosts(主机)---->Applications(监控项组)----&g ...

  9. 微信小程序入门实例之记事本

    主要实现思想都在代码的注释中,项目源码见github 首先上项目目录 app.js文件代码如下: //app.js App({ onLaunch: function() { //调用API从本地缓存中 ...

  10. UML用例图之间的关系

    在画用例图的时候,理清用例之间的关系是重点.用例的关系有泛化(generalization).扩展(extend)和包含(include).其中include和extend最易混淆.下面我们结合实例彻 ...