Item 39. Exception Safe Functions

编写异常安全代码的难点不在于抛出和捕获异常,而是在于抛出和捕获之间要做的事情。当异常从抛出

到达捕获语句的过程中,这期间执行的函数在弹栈前需要清理它所使用的任何资源。通常,这就需要片

刻的思考以及一些常识。

以String的赋值操作为例:
 
String &String::operator =( const char *str ) {
    if( !str ) str = "";
    char *tmp = strcpy( new char[ strlen(str)+1 ], str );
    delete [] s_;
    s_ = tmp;
    return *this;
}

char *tmp 这个中间变量似乎有点多余,我们“可以”写成这样:
String &String::operator =( const char *str ) {
    delete [] s_;                                       
    if( !str ) str = "";
    s_ = strcpy( new char[ strlen(str)+1 ], str );
    return *this;
}

果真如此吗?
delete [] 根据约定可以保证不抛出异常,然而new[]可能抛出异常。在未知新的内存是否分配成功的

时候,我们却把s_的内存释放掉了。于是,String对象处于一个bad state。
Herb Sutter 告诉我们在这种情况下应该这样处理:首先在不改变重要状态的一边处理那些能够引发异

常的操作,而后用不能引发异常的操作结束整个过程(First do anything that could cause an

exception "off to the side" without changing important state, and then use operations that

can't throw an exception to finish up.)。

再看一例:

错误的写法:
void Button::setAction( const Action *newAction ) {             
    delete action_; // change state!                            
    action_ = newAction->clone(); // then maybe throw?          
}

繁琐的写法:
void Button::setAction( const Action *newAction ) {             
    delete action_;                                             
    try {                                                       
        action_ = newAction->clone();                           
    }                                                           
    catch( ... ) {                                              
        action_ = 0;                                            
        throw;                                                  
    }                                                           
}

简单正确的写法:
void Button::setAction( const Action *newAction ) {
    Action *temp = newAction->clone(); // off to the side...
    delete action_; // then change state!
    action_ = temp;
}

转载于:https://www.cnblogs.com/aiwz/archive/2005/04/22/6333205.html

Item 39. 异常安全之函数(Exception Safe Functions)相关推荐

  1. C#(二):数据类型、运算符、语句、类型转换、异常捕获、函数方法定义

    数据类型.运算符.语句.类型转换.异常捕获.函数方法定义 命名约定 变量 文本 数字 布尔值 任意类型 `object` `dynamic` 声明局部变量 获取类型的默认值 数组 数组定义方法 `x ...

  2. java fatal exception_java,_运行异常:A fatal exception has occurred. Program will exit,java - phpStudy...

    运行异常:A fatal exception has occurred. Program will exit 问题: 此次异常主要是线上问题,没有直接操作服务器的权限.已知:集群其中一台正常可用,一台 ...

  3. 单例、异常、eval函数

    一.单例 01. 单例设计模式 设计模式 设计模式 是 前人工作的总结和提炼,通常,被人们广泛流传的设计模式都是针对 某一特定问题 的成熟的解决方案 使用 设计模式 是为了可重用代码.让代码更容易被他 ...

  4. java exception源码_Java异常之 Error 和 Exception

    简单了解 Java 异常 1.实际工作中,遇到的情况不可能是非常完美的. 比如:你写的某个模块,用户输入不一定符合你的要求: 你的程序要打开某个文件,这个文件可能不存在或者文件格式不对: 你要读取数据 ...

  5. Java的异常:Error与Exception

    Java的异常:Error与Exception 参考文章: (1)Java的异常:Error与Exception (2)https://www.cnblogs.com/heqiyoujing/p/11 ...

  6. Java异常:选择Checked Exception还是Unchecked Exception?

    Java包含两种异常:checked异常和unchecked异常.C#只有unchecked异常.checked和unchecked异常之间的区别是: Checked异常必须被显式地捕获或者传递,如B ...

  7. [转载] Java异常:选择Checked Exception还是Unchecked Exception?

    参考链接: Java中的已检查与未检查异常| checked或unchecked异常 Java包含两种异常:checked异常和unchecked异常.C#只有unchecked异常.checked和 ...

  8. Java异常之 Error 和 Exception

    简单了解 Java 异常 1.实际工作中,遇到的情况不可能是非常完美的. 比如:你写的某个模块,用户输入不一定符合你的要求: 你的程序要打开某个文件,这个文件可能不存在或者文件格式不对: 你要读取数据 ...

  9. Java异常:RuntimeException和Exception的区别

    Java设置了异常,旨在鼓励将方法中可能出现的异常告知给使用此方法的程序员.当然了,这种方法是比较优雅的,让我们确切的知道是在哪里出了错,并提供了异常捕获.本篇文章主要对Java中的异常进行介绍与区分 ...

最新文章

  1. 20190226-利用序列化完成小型记账程序
  2. c语言文件查找函数fread,文件函数fread
  3. IDEA修改Servlet的代码生成模板
  4. redis、memcache、mongoDB 对比
  5. python——学习笔记3
  6. android task详解,Android AsyncTask的使用详解
  7. 引用和指针的区别都有什么_C++指针与引用的区别
  8. matlab版VLFeat安装
  9. html中最小规格字体,font-size【CSS 字体大小】文字大小尺寸
  10. 关于回溯模型的两种解空间树
  11. mysql 连续天数_MYSQL面试题:统计连续打卡天数
  12. 多分类问题中sklearn的RFECV指定scoring函数
  13. 软文营销登顶销售奇迹的4U定律你知道吗?
  14. 基于微信小程序的电影院购票平台
  15. 【Linux】htop命令的使用详解
  16. 2023 年游戏项目中排名前 10 的编程语言
  17. 抽奖随机滚动_用Excel做个抽奖器吧
  18. 全球IP归属地查询 IP地址查询
  19. 首个华为HarmonyOS专业课走进校园,落地武汉大学
  20. PNAS:人类头皮记录电位的时间尺度

热门文章

  1. 注意一些坑,从app跳转到qq聊天界面。
  2. 【博客美化】09.评论带头像,且支持旋转
  3. iptables上课内容
  4. Android 5.0 Screen pinning 屏幕固定功能
  5. JEE_Ajax技术
  6. 向“3+1” SQLServer2008集群增加磁盘
  7. 图的广度优先搜索遍历
  8. 负载均衡mysql的使用_使用负载均衡集群集化 MySQL - Azure Virtual Machines | Microsoft Docs...
  9. 开发转测试没人要_iOS13beta8发布,微信再次测试新功能
  10. Python获取主机信息、开机时间和开机时长、当前登陆用户