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的專欄