2013-12-12 54 views
1

更有效的C++項目號-13,項目13:通過引用捕獲異常。也可以說 - 要通過指向工作的異常來捕獲異常,程序員必須以保證對象在控制離開功能後存在的方式定義異常對象。全局和靜態對象正常工作。如何通過引用捕獲異常來解決本地變量問題

//其中通過指針捕捉異常

class exception { ... };   // from the standard C++ 

void someFunction() 
{ 
    static exception ex;   // exception object 
    ... 
    throw &ex;      // throw a pointer to ex 
    ... 
} 
void doSomething() 
{ 
    try 
    { 
     someFunction();    // may throw an exception* 
    } 

    catch (exception *ex) 
    { // catches the exception*; 
     ...       // no object is copied 
    } 
} 

我的疑問是如何不同在通過引用捕捉異常的情況下的實例?如果它是一個局部變量(不是靜態的或全局的),那麼一旦控制離開函數,對象就不存在。那麼如何通過引用捕獲異常來解決問題?

回答

4

要捕獲一個指針,你必須拋出一個指針。要找到一個參考,您可以按值拋出一個對象。給定對象名稱的throw表達式會創建對象的副本;它並不把它的論點作爲參考。

拋出的副本稱爲異常對象並且它位於由運行時庫維護的特殊分配區域中。它的析構函數在異常傳播完成時被調用,它可能位於調用堆棧的任何位置。 C++ 11提供了使用引用計數語義手動控制異常對象生存期的附加工具。

如果趕上的值,那麼另一個副本在進入catch塊通過其價值漁獲製造,並且在離開該catch塊即使異常傳播到另一個封閉catch塊當這第二個副本被破壞。外部catch將看到原始異常對象,而內部catch未應用任何修改。

catch塊通信的能力是通過const引用的成語實現的。


順便說一句,拋出指針基本上被打破,因爲它無法處理內存不足錯誤。如果您嘗試使用new分配異常對象,但沒有更多內存,則std::bad_alloc將在程序到達throw表達式之前劫持該程序。該庫提供了一種分配例外的備選方法來提供內存不足的情況。

+0

如果我沒有錯,而我們使用引用調用,則不會創建副本。捕獲情況下的行爲是否有所不同? –

+0

@DeveshAgrawal通過參考捕捉不會產生副本。按價值捕獲,如按價值傳遞,確實會生成副本。沒有像參考文獻那樣的東西;只有價值投擲。 – Potatoswatter

+0

如果按價值投入並按引用方式獲取,則不會創建副本,對吧?因爲價值是本地的,所以一旦我們從功能中出來,它就會被破壞。 –