中国IT动力,最新最全的IT技术教程
最新100篇 | 推荐100篇 | 专题100篇 | 排行榜 | 搜索 | 在线API文档
首 页 | 程序开发 | 操作系统 | 软件应用 | 图形图象 | 网络应用 | 精文荟萃 | 教育认证 | 硬件维护 | 未整理篇 | 站长教程
ASP JS PHP工程 ASP.NET 网站建设 UML J2EESUN .NET VC VB VFP 网络维护 数据库 DB2 SQL2000 Oracle Mysql
服务器 Win2000 Office C DreamWeaver FireWorks Flash PhotoShop 上网宝典 CorelDraw 协议大全 网络安全 微软认证
硬件维护  CPU  主板  硬盘  内存  显卡  显示器  键盘鼠标  声卡音箱  打印机  机箱电源  BIOS  网卡  C#  Java  Delphi  vs.net2005
  当前位置:> 程序开发 > 编程语言 > 综合其它
Item 39. 异常安全之函数(Exception Safe Functions)
作者:未知 时间:2005-07-27 23:20 出处:CSDN 责编:chinaitpower
              摘要:Item 39. 异常安全之函数(Exception Safe Functions)

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;
}


关闭本页
 
首页 | 投资与合作 | 服务条款 | 隐私政策 | 收藏本站 | 设为首页 | 新用户注册 | 免责声明 | 使用帮助
Copyright ©2005-2008 chinaitpower.com All rights reserved. www.chinaitpower.com 版权所有