Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1828741
  • 博文数量: 195
  • 博客积分: 4227
  • 博客等级: 上校
  • 技术积分: 2835
  • 用 户 组: 普通用户
  • 注册时间: 2010-09-04 10:39
文章分类

全部博文(195)

文章存档

2013年(1)

2012年(26)

2011年(168)

分类: C/C++

2011-11-02 14:04:56

这是上一次看完Herb  Sutter的《Exceptional C++》 后形成的看法,因为懒于更新Blog,一直没有写下来。
一般讲到三个境界,很多人会联想到……#1见山是山,见水是水#2见山不是山,见水不是水#3见山还是山,见水还是水。嗯没错,区区这里说的也是这东西,只不过是有关编程,有关C++,有关异常而已。

事情源起于今天下班时间过后,老大随着他的手机铃声《上海滩》潇洒地下班了。留下区区和梁兄在办公室里,当时他好像在对一个RDI程序进行逆向工程,而区区只是在摆弄oberon。

“你觉得用C++进行异常安全性编程时最重要的范式是什么?try,catch,finally要怎么使用才得当?”梁忽然地就问了。

老实说,牛X得不得了的梁很少跟在下请教问题的(虽然这个问句有强烈的讨论意味,但是区区就权当是在被“请教”了),所以觉得应该尽可能答得好一些。

“编写异常安全的C++程序,最好就是,不要使用try,catch,finally。”——区区这样回答的。

“哦,很怪喔,那怎么能怎么处理呢?”————就知道会被追问~~

于是,那区区就说:
是这样的,有关异常的C++编程,有三个境界:

#第一个境界就是:程序中看到不try,catch,finally。
这是新手的水平,他不知道有的模块/函数是会有异常抛出的,不处理的话,程序会当掉,很多资源会不能及时正确回收。或者他写程序时反复应用errno或者检查返回值的方式来处理异常情况,排错代码和正常流程代码搅在一起,混乱不堪。

#第二个境界就是:程序中看到好多好多try,catch,finally。
这 是入门级的水平,他懂得利用抛异常的方式来处理错误情况,所以在程序中,正常的流程会统一在try里,各种错误处理,都安排在catch当中,小心翼翼地 做好的善后工作。有时候狠起来还使用catch(...)来强行把所有的异常都压下来。这样没有什么混乱?才怪,各种善后处理虽然都做了,但是他不知道要 写多少个try,多少个catch,而且经常要把思路放到catch当中去。

#第三个境界就是:程序中还是看到不try,catch,finally。
然而有不同,这一回他是手中无剑心有剑的高手境界了。
他知道异常安全的三个保证,并且懂得在什么时候分别提供#资源回收保证#数据一致性保证#无异常保证。
---他会使用C++超强的RAII(资源获取即初始化)来使得资源在产生异常时会自动回收(写一个类就可以管理一种资源,一劳永逸,不用天天catch来catch去)。
---他会使用pimpl技法(我比较喜欢叫它疙瘩技法)帮助实现RAII,并把逻辑操作分派到各个成员内部当中,使之在发生异常时保持一致性。
---他另外还会常常使用一个no throw的swap操作一次性把所有的操作完成。这样的话,对象就不会成为烂尾楼。
于是,这个高手写的类自己不用异常来打扰你,如果真的在内部其它类发生了异常,这个异常也安全地透过这个高手的类传到更上一层去,不破坏类本身的数据完整性。虽然异常还会有,但是,安全了~

所以综合来说,要写好一个异常安全的模块,最好有几个东东要牢记于心~::
异常(它会出现),RAII,pimpl,数据一致性,swap。
如果忘了,可以翻出boost::shared_ptr的源程序好好看一遍。(这句话其实没敢跟师兄说)

其实少用try catch,是对于一个相对的说法。当知道一个模块要通过抛异常来报告错误,并且这个错误的处理责任是模块调用者时,就应当使用try,别把异常给漏了。比如说boost::lexical_cast的用户~

再比如梁的模块一般最终要以c函数接口形式发布,那在模块的最上层,加一个try,也是合适的。

而且梁自己也说了,现在正在逆向的这个程序,使用了很好的SEH(这是windows的异常处理功能),所以很容易把握开发者的意图————你看,用异常处理来写程序就是好,连反汇编的可读性都比返回错误码的范式要强得多(当然,有的人不希望被逆向的)。
转自:http://blog.csdn.net/delphinew/article/details/1376439
阅读(1271) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~