zoukankan      html  css  js  c++  java
  • C语言异常处理编程的三个境界

    http://blog.csdn.net/treefish2012/article/details/17466487

    这是上一次看完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的异常处理功能),所以很容易把握开发者的意图————你看,用异常处理来写程序就是好,连反汇编的可读性都比返回错误码的范式要强得多(当然,有的人不希望被逆向的)

  • 相关阅读:
    composer 的安装以及一些插件的下载等
    linux 服务器安装php5.6
    数据库异地备份---服务器配置流程
    expect安装
    linux 服务器安装mysql5.6
    使用navicat 使用IP、用户名、密码直接连接linux服务器里面的数据库
    函数指针 指针函数
    信号量
    消息队列-Message Queue
    生成库文件,会链接依赖的库文件吗?
  • 原文地址:https://www.cnblogs.com/feng9exe/p/7246729.html
Copyright © 2011-2022 走看看