用throw-catch-finally的确方便,但是包含throw-catch-finally的程序在执行时系统要参入到管理你的代码执行顺序,如果某个模块内产生了一个异常,系统往往要在整个代码内执行全局展开,以找到一个匹配的catch/finally模块。如果要排除错误并允许代码在出现异常的地方继续执行,则系统的介入更加复杂。相应的要消耗一定的系统资源和执行速度。
我认为在可以并且方便的地方,用返回值处理比较好。如果要报告错误类型,可以用SetLastError(),很多API函数就是这样处理的,只有很少的牵涉到硬件操作的情况才使用结构化异常处理,可见前者的效率较高。

解决方案 »

  1.   

    to In355Hz:是啊,书上也是这样说的,但我想有个实际应用的例子,比如什么时候你自己throw了,为什么要用throw而不用return HRESULT;还有什么时候你用finally了?如果throw(我专指throw)主要出现于牵涉到硬件操作的时候才用,那他对我这种最底层代码就是winapi的程序员来说有什么意义?
                                   bobby
      

  2.   

    你用过IntDev么?当你给出一个不存在的属性的时候,它会蹦出一个"异常,未知的属性",
    它就是个很好的例子,试想如果有600个属性检查的过程,你用600个==号去检查么?
    至于函数的返回码,就象前面一位大哥说的一样,是效率最高的,而且在别人不知道你的
    错误类的时候也能用.
    但是在处理特别的程序的时候(我们有一个练习就是这样),这类程序往往要求很高的健壮性,
    比如说数据采集程序,要避免数据的丢失,那么一定要用结构化异常处理,在finally中起动
    一个自己的副本同时将分配的内存删去(自己死之前一定要先给出接班人),在WINDOWS的系统下,由于程序在独立的地址空间中运行,这往往能很有用.
      

  3.   

    我觉得以下几个情况可以用结构化异常处理:
    1、函数调用层次很复杂,如果一层层的检查返回值,将显得很复杂、易出错且不易取得错误类型,这样的话用SetLastError或静态变量(在Dll中要考虑多线程,使用TLS)+返回值是一个选择,但是用结构化异常处理不依赖于静态变量,显得更好一点。
    2、出错的可能性较多较隐蔽(比如读写文件),甚至有的错误不一定立刻能显现出来,如果要一步步的检察是否出错,这样的效率显然很低。这时用结构化异常处理的好处就是可以在try块内编程时可以几乎不考虑出错的可能,可以在catch/finally内对异常情况统一处理。
      

  4.   

    嗯,我有点眉目了,我总结一下两位的观点:
        1、当需要返回的结果码非常多,而且自己写的代码与客户(其他程序员)隔着很多层函数嵌套时,才用throw.
        2、finally好说,smartnose说得很清楚,把释放内存的代码全写在finally里面就准没错。
        3、catch更加好说,因为你不catch也不行。
    说到底我是明白了throw和return HRESULT及SetLastError()在功能上根本没有可以清楚划分的界限。两位再补充一点吧。:)
                          bobby
      

  5.   

    非也,非也。所谓异常,本质上是 goto 语句,提供了发生某些坏事时的另一条代码流。
    异常机制不应该用来处理“可预期的返回值”,比如打开文件失败。
    异常最好保留给真正无法预测的事件,比如浮点错,除零错。而且,错误处理里很重要的一条就是:
    再底层检查错误,在高层统一处理错误。不要滥用异常,切记!切记!![email protected]
      

  6.   

    to osee2000:什么是在底层检查错误,在高层统一处理? 这有什么好处?
      

  7.   

    好像VC里
    C++ exception (throw() catch())

    SEH(__try__finally )这两种异常是不能用在同一个函数里的吧。在C++Builder中是可以的。
      

  8.   

    事先定义好各种错误码,底层函数发现错误后直接返回错误码,但不处理。
    最上层检查到错误后,进行处理(MessageBox 或者 Log)。这样可以统一错误处理,如果想修改的话,只需要改一个地方。
      

  9.   

    是这样的,一般不要让异常强制展开,让他自己从try块到finally 块或者except块,不然会有很多的开销的
      

  10.   

        非常感谢大家对这个牛角尖问题的热心,我相信我很快就能找到答案的.特别谢谢osee2000.to osee2000:
        但我觉得这样处理也可以代替您说的方法,而且我习惯也是这样做的.
            if(出错){
                return EHandler(错误信息1,信息2,......);
            }
            BOOL EHandle(......){  //一全局处理函数
                统一进行错误处理.
            }
    这样的例子好像体现不出结构化异常处理比起return的好处.
        再有,您说结构化错误处理机制最好留给无法预测的错误,例如除零错,就是说会有以下的代码:
        if(i==0)
            throw(除零错误的标准exception);
        else
            a=a/i;
    但其实不需进行这句判断,系统也会自动产生除零异常.等于说我并没必要产生这种错误.再说如果真有一种错误是无法预测并要有我来产生,那他就不是一个无法预测的错误了,他就可以被普通的return来处理了.
        还有,越说越兴奋了^_^,如果我接到了一个除零的异常,除了什么也不干跳倒下一行代码继续执行和显示MessageBox之外,我还能写些什么有利于程序健壮性的代码?因为这时候我根本不知道这种不可预测的异常是在什么情况下产生,由谁产生的. 那干嘛还要产生除零异常,进而要问,干嘛要产生不可预测的错误异常,统一由系统产生MessageBox或者根本不管不就得了.发言完毕谢谢.^_^(提醒大家,我现在不懂的是什么时候该用throw,而不是整个结构化异常处理机制,我觉得finally是很有用的.)
      

  11.   

        我最近发现了throw的确有用的用处,就是再没有任何办法中断程序执行的时候throw之,例如在构造函数里面使用,除此之外,throw的真正的好处还请大家告诉我.