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

文章目录

  • 异常情况
  • 总结

异常情况

 当我们的析构函数发生异常的时候:C++并不禁止析构函数吐出(emit)异常。

class Widget {
public:...~Widget() { ... } // 假设这可能会引发异常
};
void doSomething()
{std::vector<Widget> v;...
} // v在这里自动销毁

 假设v中包含多个Widget对象,销毁第一个时发生异常,销毁第二个时也发挥异常,将产生未定义的行为。
 如果析构函数需要执行一个可能会失败并抛出异常的操作,该怎么办?例如,假设你正在使用一个用于数据库连接的类:

class DBConnection {
public:...static DBConnection create(); 	// 返回DBConnection对象的函数;// 为简单起见,省略了参数void close(); // 关闭连接联系;如果关闭失败,抛出异常
}; class DBConn { // 用来来管理DBConnection对象的类
public: // ...~DBConn() // 确保数据库连接总是关闭的{ db.close();}
private:DBConnection db;
};{ // 开启一个块DBConn dbc(DBConnection::create()); // 创建DBConnection对象// 然后把它交给DBConn对象来管理... // 通过DBConn接口使用DBConnection对象} // block结束时,DBConn对象被销毁,自动在DBConnection对象上调用close

如果调用产生异常,DBConn的析构函数将传播该异常,即允许它离开析构函数。这会导致麻烦,因为析构函数吐出的异常很难处理。
有两种主要方法可以避免这种麻烦。DBConn的析构函数可以:

  • 如果发生close抛出异常,就终止程序,通常可以调用abort:
DBConn::~DBConn()
{try { db.close(); }catch (...) {在日志中记录close调用失败;std::abort();}
}
  • 吞下调用close引起的异常:
DBConn::~DBConn()
{try { db.close(); }catch (...) {在日志中记录close调用失败;}
}

这两种方法都不是特别有吸引力。
这两种方法的问题在于,程序无法对导致close抛出异常的条件做出反应。
更好的策略是设计DBConn的接口,以便其使用者有机会对可能出现的问题作出反应。

class DBConn {
public:...void close() // 供客户使用的新函数{ db.close();closed = true;}~DBConn(){if (!closed) {try { // 如果客户没有关闭,则关闭连接db.close(); }catch (...) { 			// 如果关闭失败,在日志中记录close调用失败; 	// 记录下来并... 				// 终止或吞下}}}
private:DBConnection db;bool closed;
};

将调用close的责任从DBConn的析构函数转移到DBConn的客户,(DBConn的析构函数依然包含一个“备用的”调用)。

总结

  • 析构函数永远不应该吐出(emit)异常。如果在析构函数中调用的函数可能抛出异常,则析构函数应该捕获任何异常,然后将其吞下或终止程序。
  • 如果类客户需要能够对操作期间抛出的异常做出反应,则类应该提供执行该操作的普通(即非析构函数)函数。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/313187.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一文带你了解华为云DevCloud为何能全面领跑中国DevOps云服务市场

近日&#xff0c;国际权威调研机构IDC发布了《IDC MarketScape&#xff1a;中国DevOps云服务市场2019厂商评估》报告&#xff0c;该报告从战略和能力两个维度对国内主流DevOps云厂商进行了评估&#xff0c;报告显示&#xff0c;华为云位于 IDC MarketScape “中国DevOps云服务 …

[电子书制作]Excel催化剂输出内容汇总PDF及Word版本分享

Excel催化剂在2018年开始&#xff0c;陆续写出了230篇高质量原创性文章&#xff0c;将Excel催化剂插件的开发过程及使用方法全方位地通过文字的方式给广大网友们分享了。电子书下载方式同样地&#xff0c;为了减少大家过多繁琐的资料下载途径&#xff0c;电子书的下载路径和之前…

深入理解.NET Core的基元: deps.json, runtimeconfig.json, dll文件

原文链接&#xff1a; Deep-dive into .NET Core primitives: deps.json, runtimeconfig.json, and dlls作者&#xff1a; Nate McMasterC#编译器(The C# Compiler)C#的编译器可以将cs文件转换为dll文件, 即程序集文件。程序集文件是一个便携的可执行格式文件, 借助.NET Core,它…

C# 8.0 的默认接口方法

例子直接看例子有这样一个接口&#xff1a; 然后有三个它的实现类&#xff1a; 然后在main方法里面调用&#xff1a; 截至目前&#xff0c;程序都可以成功的编译和运行。 IPerson接口变更 突然&#xff0c;我想对所有的人类添加一个新的特性&#xff0c;例如&#xff0c;添加一…

convolutional layer 源代码

http://blog.csdn.net/xizero00/article/details/51049858 一、 卷积层的作用简介 卷积层是深度神经网络中的一个重要的层&#xff0c;该层实现了局部感受野&#xff0c;通过这种局部感受野&#xff0c;可以有效地降低参数的数目。我们将结合caffe来讲解具体是如何实现卷积层的…

在.net core3.0中使用SignalR实现实时通信

最近用.net core3.0重构网站&#xff0c;老大想做个站内信功能&#xff0c;就是有些耗时的后台任务的结果需要推送给用户。一开始我想简单点&#xff0c;客户端每隔1分钟调用一下我的接口&#xff0c;看看是不是有新消息&#xff0c;有的话就告诉用户有新推送&#xff0c;但老大…

活动最后72小时:购书优惠劵,折后再折,赶紧来抢啊

1024程序员节当当网计算机图书每满100减50&#xff01;满200减100&#xff01;满300-150&#xff01;机械工业出版社华章公司联合当当网特意为【DotNET技术圈】用户申请了一批可与满减叠加使用的“满200减30”的图书优惠码&#xff0c;优惠码使用后相当于&#xff1a;400减230 …

ubuntu指令模式修改IP等信息

http://blog.igevin.info/posts/ubuntu-1404-ip-dns/ 先安装vim&#xff0c;然后按a启动编辑&#xff0c;两次按大写的Z结束编辑并保存。 修改/etc/network/interfaces设置静态IP sudo vi /etc/network/interfaces用下面的代码替换有关eth0的内容&#xff1a; # The primary…

C# 8 新特性 - using 声明

using语句块 尽管.NET Core运行时有垃圾收集器&#xff08;GC&#xff09;来负责内存清理工作&#xff0c;但是我们还是要自己确保当非托管资源不再使用的时候应该被清理掉。以前针对实现了IDisposable接口的对象&#xff0c;我们经常会使用using 语句块来这样做&#xff1a; 这…

Ubuntu failed to fetch ... hash sum mismatch

http://askubuntu.com/questions/41605/trouble-downloading-packages-list-due-to-a-hash-sum-mismatch-error Just remove all the content of /var/lib/apt/lists directory: sudo rm -rf /var/lib/apt/lists/*then run: sudo apt-get update

.Net Core3.0依赖注入DI

构建ASP.NET Core应用程序的时候&#xff0c;依赖注入已成为了.NET Core的核心&#xff0c;这篇文章&#xff0c;我们理一理依赖注入的使用方法。不使用依赖注入首先&#xff0c;我们创建一个ASP.NET Core Mvc项目&#xff0c;定义个表达的爱服务接口&#xff0c;中国小伙类实现…

.Net轻量状态机Stateless

很多业务系统开发中&#xff0c;不可避免的会出现状态变化&#xff0c;通常采用的情形可能是使用工作流去完成&#xff0c;但是对于简单场景下&#xff0c;用工作流有点大财小用感觉&#xff0c;比如订单业务中&#xff0c;订单状态的变更&#xff0c;涉及到的状态量不是很多&a…

运行Deeplab遇到‘Unexpected label’

https://groups.google.com/forum/#!topic/caffe-users/CLF4IZ2Tkqk This problem lies in the reading of *.png image(opencv auto insert filtered the pngs edge) So we can just change all the label *.png image to *.bmp format, then all gone right.

Asp.net Core全局异常监控和记录日志

前言系统异常监控可以说是重中之重&#xff0c;系统不可能一直运行良好&#xff0c;开发和运维也不可能24小时盯着系统&#xff0c;系统抛异常后我们应当在第一时间收到异常信息。在Asp.net Core里我使用拦截器和中间件两种方式来监控异常。全局异常监控的数据最好还是写入数据…

Deeplab 在Qt Creator下编译报错undefined reference to Mat_xxx

https://github.com/TheLegendAli/DeepLab-Context/issues/8 1. 修改工程根目录下的CMakeLists.txt 末尾加上 find_package(MATIO REQUIRED) include_directories(${MATIO_INCLUDE_DIR}) 2. 修改src/caffe/CMakeLists.txt target_link_libraries(caffe proto...) 中加…

在.Net Core 3.0中尝试新的System.Text.Json API

.NET Core 3.0提供了一个名为System.Text.Json的全新命名空间&#xff0c;它支持reader/writer&#xff0c;文档对象模型&#xff08;DOM&#xff09;和序列化程序。在此博客文章中&#xff0c;我将介绍它如何工作以及如何使用。 获取JSON库 如果以.NET Core为目标,请安装.NET …

caffe blob操作

http://blog.luoyetx.com/2015/10/reading-caffe-2/ Blob 在 Caffe 中扮演了重要的角色&#xff0c;用于存储数据和网络参数&#xff0c;同时也在 CPU 和 GPU 之间做了数据同步。Blob 原本在 Caffe 中被表示为一个 4 维数组 (num x channel x height x width)&#xff0c;现在可…

extern __shared__

http://blog.csdn.net/openhero/article/details/3890578 首先是讲一下shared的memory的两种使用方法&#xff0c;然后讲解一下shared memory的bank conflict的问题&#xff0c;这个是shared memory访问能否高效的问题所在&#xff1b; Shared memory的常规使用&#xff1a;…

SiteServer CMS 新版本 V6.13(2019年11月1日发布)

欢迎来到 SiteServer CMS V6.13 版本&#xff0c;经过两个月的连续迭代开发&#xff0c;V6.13版本新增了几项重要功能&#xff0c;我们希望你会喜欢&#xff0c;一些关键的亮点包括&#xff1a;。新增功能及BUG 修复经过两个月的连续迭代开发&#xff0c;V6.13 版本新增了部分功…

CUDA的global内存访问的问题

http://blog.csdn.net/OpenHero/article/details/3520578 关于CUDA的global内存访问的问题&#xff0c;怎么是访问的冲突&#xff0c;怎样才能更好的访问内存&#xff0c;达到更高的速度。下面先看几张图&#xff0c;这些图都是CUDA编程手册上的图&#xff0c;然后分别对这些…