2011-12-05 36 views
4

當我編寫我的try/catch塊時,我總是按值引發對象並以引用形式捕獲對象。我也應用了大多數派生類必須先來的規則。通過值傳遞的異常

今天我試圖抓住BY VALUE違反這條主要規則。下面的代碼執行沒有任何問題,並打印"A4"

問題:什麼類型的CCA參數被傳遞給執行的異常處理程序?拋出的原始對象是CCB將值傳遞給CCA對象:這是內存切片問題還是某種腐敗的示例,即對象CCA不能完全信任?

問候

AFG

class CCA{ 
     int m_value; 
    public: 
     CCA(int value) : m_value(value){}    
    }; 

    class CCB : public CCA{ 
    public: 
     CCB(int value): CCA(value){} 
    }; 


    main(){  
     try{ 
       throw CCB(4); 
     }catch(CCA a){ 
       std::cout << " A:" << a.value() << std::endl; 
       // this is the catch clause that executes 
     }catch(CCB b){ 
      std::cout << " B:" << b.value() << std::endl; 
     }  
} 
+1

是的,切片發生在這裏。 –

+0

[通過引用捕獲異常]的可能重複(http://stackoverflow.com/questions/8350526/catching-exceptions-by-reference) – FailedDev

+1

如果派生類不添加任何數據成員,則切片對象可能仍然工作或虛擬功能的基地。這並不意味着它沒有被切片。 –

回答

3

切片

:基座複製構造的不能從派生的類型中的一個辨別真正相同類型的參數
struct Base { 
    Base(Base const &); // must accept any derived class 
}; 
1

異常的捕獲塊始終按照代碼中的順序選擇。所以,如果你逆轉程序打印的異常順序B:4

在你的代碼中,第一個catch子句已被選中,基類的複製構造函數傳遞了原始的複製實例,但它將是一個真正的基類實例。

通常的解決方案是以最接近第一順序提供捕獲塊並通過引用傳遞參數。