设为首页  
联系我们  
加入收藏  
网页制作 冲浪宝典 图形图像 操作系统 软件教学 编程开发 认证考试 安全技术 站长专区 文学驿站 娱乐天地 游戏天地 办公软件
文章搜索
您的位置: 首页 >> 文章首页 >> 编程开发 >> Visual C++ >> 如何编写异常安全的C++代码
精品推荐
Visual C++点击TOP10
·利用mfc编写activex控件
·用WINSOCK实现聊天室的VC++程序设计
·用vc实现生产者消费者问题
·DirectX8.0
·C/C++ 大量经典编程书籍下载
·VC快捷键大全
·CreateFileMapping的MSDN翻译和使用心得
·Windows环境下的麦克风录音系统
·挂钩Windows API
·如何开发OPC Server
编程开发点击TOP10
·数字小键盘指法练习
·ASP.NET 程序中常用的三十三种代码
·用C语言编通讯录程序(初学者级别的)
·我写的Java学生成绩管理系统源代码
·CHK文件恢复工具
·java笔试题
·单片机模拟I2C总线及24C02(I2C EEPROM)读写实例(源代码)
·Modem 常用AT指令集
·异常java.sql.SQLException: Io exception:The Network Adapter could not establish connection
·C++经典电子书下载
精选专题

如何编写异常安全的C++代码

作者: 来源: 时间:2006-4-24 14:28:15

如何编写异常安全的C++代码(1)

    关于C++中异常的争论何其多也,但往往是一些不合事实的误解。异常曾经是一个难以用好的语言特性,幸运的是,随着C++社区经验的积累,今天我们已经有足够的知识轻松编写异常安全的代码了,而且编写异常安全的代码一般也不会对性能造成影响。

    使用异常还是返回错误码?这是个争论不休的话题。大家一定听说过这样的说法:只有在真正异常的时候,才使用异常。那什么是“真正异常的时候”?在回答这个问题以前,让我们先看一看程序设计中的不变式原理。

  对象就是属性聚合加方法,如何判定一个对象的属性聚合是不是处于逻辑上正确的状态呢?这可以通过一系列的断言,最后下一个结论说:这个对象的属性聚合逻辑上是正确的或者是有问题的。这些断言就是衡量对象属性聚合对错的不变式。

  我们通常在函数调用中,实施不变式的检查。不变式分为三类:前条件,后条件和不变式。前条件是指在函数调用之前,必须满足的逻辑条件,后条件是函数调用后必须满足的逻辑条件,不变式则是整个函数执行中都必须满足的条件。在我们的讨论中,不变式既是前条件又是后条件。前条件是必须满足的,如果不满足,那就是程序逻辑错误,后条件则不一定。现在,我们可以用不变式来严格定义异常状况了:满足前条件,但是无法满足后条件,即为异常状况。当且仅当发生异常状况时,才抛出异常。

  关于何时抛出异常的回答中,并不排斥返回值报告错误,而且这两者是正交的。然而,从我们经验上来说,完全可以在这两者中加以选择,这又是为什么呢?事实上,当我们做出这种选择时,必然意味着接口语意的改变,在不改变接口的情况下,其实是无法选择的(试试看,用返回值处理构造函数中的错误)。通过不变式区别出正常和异常状况,还可以更好地提炼接口。

  对于异常安全的评定,可分为三个级别:基本保证、强保证和不会失败。

  基本保证:确保出现异常时程序(对象)处于未知但有效的状态。所谓有效,即对象的不变式检查全部通过。
  强保证:确保操作的事务性,要么成功,程序处于目标状态,要么不发生改变。
  不会失败:对于大多数函数来说,这是很难保证的。对于C++程序,至少析构函数、释放函数和swap函数要确保不会失败,这是编写异常安全代码的基础。

  首先从异常情况下资源管理的问题开始.很多人可能都这么干过:

Type* obj = new Type;
try{  do_something...}
catch(...){ delete obj; throw;}

  不要这么做!这么做只会使你的代码看上去混乱,而且会降低效率,这也是一直以来异常名声不大好的原因之一. 请借助于RAII技术来完成这样的工作:

auto_ptr<Type> obj_ptr(new Type);
do_something...

  这样的代码简洁、安全而且无损于效率。当你不关心或是无法处理异常时,请不要试图捕获它。并非使用try...catch才能编写异常安全的代码,大部分异常安全的代码都不需要try...catch。我承认,现实世界并非总是如上述的例子那样简单,但是这个例子确实可以代表很多异常安全代码的做法。在这个例子中,boost::scoped_ptr是auto_ptr一个更适合的替代品。

  现在来考虑这样一个构造函数:

Type() : m_a(new TypeA), m_b(new TypeB){}

  假设成员变量m_a和m_b是原始的指针类型,并且和Type内的申明顺序一致。这样的代码是不安全的,它存在资源泄漏问题,构造函数的失败回滚机制无法应对这样的问题。如果new TypeB抛出异常,new TypeA返回的资源是得不到释放机会的.曾经,很多人用这样的方法避免异常:

Type() : m_a(NULL), m_b(NULL){
     auto_ptr<TypeA> tmp_a(new TypeA);
     auto_ptr<TypeB> tmp_b(new TypeB);

共4页 9 7 [1] [2] [3] [48 :>

如何编写异常安全的C++代码 相关文章:
如何编写异常安全的C++代码 相关软件:
特别声明:本站除部分特别声明禁止转载的专稿外的其他文章可以自由转载,但请务必注明出处和原始作者。文章版权归文章原始作者所有。对于被本站转载文章的个人和网站,我们表示深深的谢意。如果本站转载的文章有版权问题请联系编辑人员,我们尽快予以更正。
转载请注明来源:http://www.xgdown.com