第17章 用于大型程序的工具(3)
17.1.4 重新抛出
在进行了一些校正行动之后,catch可能确定该异常必须由函数调用链中更上层的函数来处理,catch可以通过重新抛出(rethrow)将异常传递给函数调用链中更上层的函数。重新抛出是后面不跟类型或表达式的一个throw。
空throw语句将重新抛出异常对象,它只能出现在catch或者从catch调用的函数中。如果在处理代码不活动时碰到空throw,就调用terminate函数。
虽然重新抛出不指定自己的异常,但仍然将一个异常对象沿链向上传递,被抛出的异常时原来的异常对象,而不是catch形参。
一般而言,catch可以改变它的形参。在改变它的形参之后,如果catch重新抛出异常,那么,只有当说明符是引用的时候,才会传播这些改变。
try
{
throw range_error("error~");
}
catch(exception &e) //e was a reference & here
{
cout<<e.what()<<endl;
throw;
}
try
{
throw range_error("error~");
}
catch(exception &e) //e was a reference & here
{
cout<<e.what()<<endl;
throw;
}try
{
throw range_error("error~");
}
catch(exception e) //e was a class instance here.
{
cout<<e.what()<<endl;
throw;
}
try
{
throw range_error("error~");
}
catch(exception e) //e was a class instance here.
{
cout<<e.what()<<endl;
throw;
}17.1.5 捕获所有异常的处理代码
除了为每个可能的异常提供特定catch子句之外,因为不可能知道可能被抛出的所有异常,所以可以使用捕获所有异常catch子句(catch-all)的。捕获所有异常的catch子句形式为(...)。
捕获所有异常的catch子句与任意类型的异常都匹配。
try
{
throw range_error("error~");
}
catch(...)
{
throw;
}
try
{
throw range_error("error~");
}
catch(...)
{
throw;
}如果catch(...)与其他catch子句结合使用,它必须是最后一个,否则,任何跟在它后面的catch子句都将不能被匹配。
17.1.6 函数测试块与构造函数
进入构造函数函数体之前处理构造函数初始化式,构造函数函数体内部的catch子句不能处理在处理构造函数初始化式时可能发生的异常。
为了处理来自构造函数初始化式的异常,必须将构造函数编写为函数测试块(function try block)。可以使用函数测试块将一组catch子句与函数联成一个整体。
BaseManager(const BaseManager &i)try:p(i.p),use(i.use){/*function body*/}
catch(...){
throw;
}
BaseManager(const BaseManager &i)try:p(i.p),use(i.use){/*function body*/}
catch(...){
throw;
}
摘自 xufei96的专栏
补充:软件开发 , C++ ,