设为首页  
联系我们  
加入收藏  
网页制作 冲浪宝典 图形图像 操作系统 软件教学 编程开发 认证考试 安全技术 站长专区 文学驿站 娱乐天地 游戏天地 办公软件
文章搜索
您的位置: 首页 >> 文章首页 >> 编程开发 >> 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++代码(2)      m_a = tmp_a.release();
     m_b = tmp_b.release();
}

  当然,这样的方法确实是能够实现异常安全的代码的,而且其中实现思想将是非常重要的,在如何实现强保证的异常安全代码中会采用这种思想.然而这种做法不够彻底,至少析构函数还是要手动完成的。我们仍然可以借助RAII技术,把这件事做得更为彻底:shared_ptr<TypeA> m_a; shared_ptr<TypeB> m_b;这样,我们就可以轻而易举地写出异常安全的代码:

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

  如果你觉得shared_ptr的性能不能满足要求,可以编写一个接口类似scoped_ptr的智能指针类,在析构函数中释放资源即可。如果类设计成不可复制的,也可以直接用scoped_ptr。强烈建议不要把auto_ptr作为数据成员使用,scoped_ptr虽然名字不大好,但是至少很安全而且不会导致混乱。

  RAII技术并不仅仅用于上述例子中,所有必须成对出现的操作都可以通过这一技术完成而不必try...catch.下面的代码也是常见的:

a_lock.lock(); 
try{ ...} catch(...) {a_lock.unlock();throw;}
a_lock.unlock();

  可以这样解决,先提供一个成对操作的辅助类:

strUCt scoped_lock{
    eXPlicit scoped_lock(Lock& lock) : m_l(lock){m_l.lock();}
    ~scoped_lock(){m_l.unlock();}
private:  
    Lock& m_l;
};

  然后,代码只需这样写:

scoped_lock guard(a_lock);
do_something...

    清晰而优雅!继续考察这个例子,假设我们并不需要成对操作, 显然,修改scoped_lock构造函数即可解决问题。然而,往往方法名称和参数也不是那么固定的,怎么办?可以借助这样一个辅助类:

template<typename FEnd, typename FBegin>
struct pair_guard{
    pair_guard(FEnd fe, FBegin fb) : m_fe(fe) {if (fb) fb();}
     ~pair_guard(){m_fe();}
private:
     FEnd m_fe;
     ...//禁止复制
};
typedef pair_guard<function<void () > , function<void()> > simple_pair_guard;

  好了,借助boost库,我们可以这样来编写代码了:

simple_pair_guard guard(bind(&Lock::unlock, a_lock), bind(&Lock::lock, a_lock) );
do_something...

  我承认,这样的代码不如前面的简洁和容易理解,但是它更灵活,无论函数名称是什么,都可以拿来结对。我们可以加强对bind的运用,结合占位符和reference_wrapper,就可以处理函数参数、动态绑定变量。所有我们在catch内外的相同工作,交给pair_guard去完成即可。

  考察前面的几个例子,也许你已经发现了,所谓异常安全的代码,竟然就是如何避免try...catch的代码,这和直觉似乎是违背的。有些时候,事情就是如此违背直觉。异常是无处不在的,当你不需要关心异常或者无法处理异常的时候,就应该避免捕获异常。除非你打算捕获所有异常,否则,请务必把未处理的异常再次抛出。try...catch的方式固然能够写出异常安全的代码,但是那样的代码无论是清晰性和效率都是难以忍受的,而这正是很多人抨击C++异常的理由。在C++的世界,就应该按照C++的法则来行事。

  如果按照上述的原则行事,能够实现基本保证了吗?诚恳地说,基础设施有了,但技巧上还不够,让我们继续分析不够的部分。

  对于一个方法常规的执行过程,我们在方法内部可能需要多次修改对象状态,在方法执行的中途,对象是可能处于非法状态的(非法状态 != 未知状态),如果此时发生异常,对象将变得无效。利用前述的手段,在pair_guard的析构中修复对象是可行的,但缺乏效率,代码将变得复杂。最好的办法是......是避免这么作,这么说有点不厚道,但并非毫无道理。当对象处于非法状态时,意味着此时此刻对象不能安全重入、不能共享。现实一点的做法是:

  a.每一次修改对象,都确保对象处于合法状态

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

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