这事篇读书笔记,只记录自己的理解和总结,一般情况不对其举例子具体说明,因为那正是书本身做的事情,我的笔记作为梳理和复习之用,划重点。我推荐学C++的人都好好读一遍Effective C++ 系列,真是好书啊,对于学完C++ 基础知识的人,这是本高阶秘籍。

笔记

条款 9 - 15 关注的主题是异常。关注1、异常可能引起的资源泄露(强烈推荐使用智能指针)2、异常是如何抛出的和3、异常的成本。目的是写出 exception-safe 的程序。

  • 条款9: 利用 destructor避免资源泄露

    这个条款是说如果异常被抛出到调用端,但是调用端没有catch, 如果调用端是指针,用来析构指针的delete语句可能因为异常被抛出而跳过,导致资源泄露。最好的办法就是不用指针,用临时对象,或者说用行为类似指针的临时对象(为什么非要用类似指针的行为呢?为了多态),临时对象会在对象生存期结束的时候析构,在析构函数中delete(如果有指针的话) 释放资源。这里的原则就是所谓RAII(Resource Acquisition Is Initialization),在具体实践上就是使用智能指针,C++11 中提供了std::shared_ptr 和 std::unique_ptr,目的就是为了避免资源泄露。

  • 条款10:在 constructor 内阻止资源泄露。 这个条款举例子说明了如果在对象构造时发生了异常,这个时候因为构造未完成故不会调用该对象的析构函数,该对象的指针成员面临着没有delete 的风险,导致资源泄露。解决办法跟条款9一样,想用指针的时候使用智能指针。

  • 条款11:禁止异常流出destructors 之外。 这个条款是要说明,如果异常发生在destuctor中,不要将其抛出。 理由1是因为如果这个destuctor是因为某个异常而调用的,在这时候再次发生异常并抛出会导致程序 terminate,程序将会终结,也就是最不喜欢看到的程序崩了。处理方式是把异常给吞了,如下面的例子。理由2是如果异常被抛出,引起异常的函数后面的代码都没有被执行,析构函数没有析构完。因此要尽力阻止异常被destrucor 抛出。

~AClass(){
try{
a_function_may_throw_exception();
}catch(...){
// done nothing.
}
}
  • 条款12:了解“抛出一个异常excption” 与“传递一个参数”或者“调用一个虚函数”之间的差异。 首先得明确一点, 抛出异常,事实上也是抛出异常对象,看上去跟传递对象参数是很类似的。(1) 但是,异常在抛出的时候总是伴随着对象copy行为(想想这是为什么,提示与局部对象生存期有关),也因此在效率上发生折扣。常见参数的传递的方式有 by value, by reference, by pointer. 不管是 by value 还是 by reference 抛出异常实例都会引起复制,捕捉异常时 by value 还要多复制一次。 throw by pointer 和 pass by pointer。 都是传递指针的副本,千万不要传递一个指向局部对象的指针,否则会获得一个指向已销毁的对象的指针。(2) 传递exception 不会发生隐式类型转化,除非是有型指针转为 void* 或者是继承架构中的转化(catch base 的可以catch derived 的异常),catch 语句中遵循 first fit, 即第一个匹配的就被捕捉,所以 base exception 会拦截 derived excetion。(因此应该让catch derived excaption 的语句放在前面)。
  • 条款13:以 by reference 的方式捕捉异常。 无论如何不要用 by pointer 方式捕捉异常; by value 传递会有slice 问题而且比 by reference 多复制一次。综合条款 12 和13 ,结论就是使用 by reference 的方式捕捉异常。
  • 条款14:明智运用exception specifications。 这是一把双刃剑,一方面对于函数希望提供什么样的exception 提供了说明,另外也带来了不安全的行为。unexcepted 函数默认终结程序,如果违反了 exception specification 会调用unexception函数。记住1.不要和模板 template 混用;2.不要对回调函数使用exception specification.

Note:

  1. void foo() throw(); // 含义是不抛出异常
  2. void foo() throw(A,B,C); // 含义是可能抛出A,B,C 型异常
  3. 书中76 页中介绍了 set_unexpected()函数和将非预期的异常转化为已知异常的技术,可以较为安全的处理unexpected 发生。
  • 条款15:了解异常处理(excption handling)的成本。 成本主要是三点:1.为了支持异常,程序需要做大量簿记工作,消耗额外的内存和时间,而且因为只要程序库或者用户代码任何一处用了异常处理,编译器就必须提供对异常处理的支持能力。 2. 编译器实现try语句块和 excpetion specification 带来的代码膨胀和性能损失,2000年之前作者写这本书的时候,得到的消息和测试结果是 5%-10%的损失,不知道现在谁否有提升。 3.抛出异常的损失,可能比正常的函数返回要慢三个数量级。注意,这个只是在发生异常并抛出的时候才有,而异常应该是比较少发生才是。

总结

  1. 为了异常安全,使用智能指针;
  2. 析构函数不要抛出异常,应该吞掉;
  3. 捕捉catch 异常应该 by reference;
  4. 异常处理是有成本的。(迷思:这些成本如今是否得到优化,或者项目可以容忍?如果我开始一个新项目,我要不要使用异常处理?)

《More Effective C++ 》读书笔记(二)Exception 异常的更多相关文章

  1. Effective STL 读书笔记

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

  2. Effective STL读书笔记

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

  3. 《你必须知道的.NET》读书笔记二:小OO有大原则

    此篇已收录至<你必须知道的.Net>读书笔记目录贴,点击访问该目录可以获取更多内容. 一.单一职责原则 (1)核心思想:一个类最好只做一件事,只有一个引起它变化的原因 (2)常用模式:Fa ...

  4. spring揭秘 读书笔记 二 BeanFactory的对象注册与依赖绑定

    本文是王福强所著<<spring揭秘>>一书的读书笔记 我们前面就说过,Spring的IoC容器时一个IoC Service Provider,而且IoC Service Pr ...

  5. how tomcat works 读书笔记(二)----------一个简单的servlet容器

    app1 (建议读者在看本章之前,先看how tomcat works 读书笔记(一)----------一个简单的web服务器 http://blog.csdn.net/dlf123321/arti ...

  6. ES6读书笔记(二)

    前言 前段时间整理了ES6的读书笔记:<ES6读书笔记(一)>,现在为第二篇,本篇内容包括: 一.数组扩展 二.对象扩展 三.函数扩展 四.Set和Map数据结构 五.Reflect 本文 ...

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

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

  8. Effective Java读书笔记完结啦

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

  9. spring揭秘 读书笔记 二 BeanFactory的对象注冊与依赖绑定

    本文是王福强所著<<spring揭秘>>一书的读书笔记 我们前面就说过,Spring的IoC容器时一个IoC Service Provider,并且IoC Service Pr ...

  10. 【记】《.net之美》之读书笔记(二) C#中的泛型

    前言 上一篇读书笔记,很多小伙伴说这本书很不错,所以趁着国庆假期,继续我的读书之旅,来跟随书中作者一起温习并掌握第二章的内容吧. 一.理解泛型 1.为什么要使用泛型?-----通过使用泛型,可以极大地 ...

随机推荐

  1. js实现限制上传文件大小

    <html> <head> <script type="text/javascript"> var isIE = /msie/i.test(na ...

  2. Office365学习笔记—Lookup类型加载条目过多解决方案

    1,随着接触的项目越来越多,遇到的各种奇葩的问题也越来越多,不得不说,SharePoint是个好东西,提高了开发效率,简化了很多基础的功能.但是令人头疼的问题是,当你想做个稍微复杂点的功能,就不得不研 ...

  3. sharepoint rest api Add ListItem 报错

    Recently, I was trying to create a list item using Rest API on Sharepoint 2013. I got the following ...

  4. ubuntu 如何进行文件、夹删除等操作

    rm [选项] 文件-f, --force 强力删除,不要求确认-i 每删除一个文件或进入一个子目录都要求确认-I 在删除超过三个文件或者递归删除前要求确认-r, -R 递归删除子目录-d, --di ...

  5. BZOJ 3053: The Closest M Points(K-D Tree)

    Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1235  Solved: 418[Submit][Status][Discuss] Descripti ...

  6. 如何做好一个优秀的web项目心得

    最近利用空余的时间(坐公交车看教程视频),想了很多自己做的做果项目的优缺点,重新了解了前后端分离,前端工程化等概念学习,思考如何打造好一个优秀的web前端项目. 前端准备篇 前端代码规范:制定前端开发 ...

  7. jQuery属性操作之.attr()

    目录 .attr() 调用形式:$("xxx").attr(name) 调用形式:$("xxx").attr(name,value); 调用形式:$(" ...

  8. svg路径动画心得

    svg动画,随着路线运动,项目中需要用到,接触的时候感觉很高级,但是不会-无从下手呀!于是在网上找相关资料,先借鉴再修改成自己的. <svg width="500" heig ...

  9. Vue 子组件接收父组件的值

    1.父组件 <template> <div id="rightmenu8"> <rightmenu7 ref="rightmenu7&quo ...

  10. C# 依据鼠标坐标取网页内成员坐标.ie

    C# 根据鼠标坐标取网页内成员坐标.ie 有时候你需要后台获取ie浏览器 鼠标所在位置的元素坐标,然而你使用屏幕坐标是不可行的 所以我们需要把坐标转换成浏览器内坐标 然后再通过elementFromP ...