[+]文章目录
◆ 1、当catch语句捕获一个异常后,可能不能完全处理异常,完成某些操作后,该异常必须由函数链中更上级的函数来处理,这时catch子句可以 重新抛出(rethrow)该异常,把异常传递给函数调用链中更上级的另一个catch子句,由它进行进一步处理。

重新抛出表达式仍为: throw;
但仅有一个关键字,因为异常类型在catch语句中已经有了,不必再指明。

被重新抛出的异常就是原来的异常对象。但是重新抛出异常的catch子句应该把自己做过的工作告诉下一个处理异常的catch子句,往往要对异常对象做一定修改,以表达某些信息,因此catch子句中的异常声明必须被声明为引用,这样修改才能真正做在异常对象自身中。

◆ 2、通用catch子句(catch_all):
    catch(...)
    {/*代码*/}

任何异常都可以进入这个catch子句。这里的三个点称为省略号。花括号中的复合语句用来执行指定操作。

异常发生后按栈展开(stack unwinding)退出,动态分配的非类对象资源不会自动释放的,通常在catch_all子句中释放。例如:
void fun1()
{
       int *res;
       res=new int[100]; //定义一个资源对象
       try{
              //代码包括使用资源res和某些可能引起异常抛出的操作
       } //异常可能有多种
       catch(...)//不论是那种异常都在此释放
       {
              delete [] res; //释放资源对象res
              throw; //重新抛出异常
       }
       delete [] res; //正常退出前释放资源对象res;
}

◆ 3、 catch_all子句可以单独使用,也可以与其它catch子句联合使用。如果联合使用,它必须放在相关catch子句表的最后。

catch子句被检查的顺序与它们在try块之后排列顺序相同,一旦找到了一个匹配,则后续的catch子句将不再检查,按此规则,catch_all子句(catch(...){})处理表前面所列各种异常之外的异常。

如果只用catch_all子句进行某项操作,则其他的操作应由catch子句重新抛出异常,逆调用链去查找新的处理子句来处理,不能在子句列表中再安排一个处理同一异常的子句,因为第二个子句是永远执行不到的。 

« 前一篇