2009-10-31 64 views
32

C++中的異常對象的範圍是什麼? catch處理程序執行後它是否超出範圍?另外,如果我創建一個未命名的異常對象並將其拋出,那麼在捕獲該異常時,如果我通過const引用或非const引用來捕獲異常,它會影響嗎?C++中的異常對象的範圍

+3

你問的是*生命*嗎? – Joren 2009-10-31 11:45:23

+0

是的,它會在什麼時候被破壞? – Naveen 2009-10-31 11:46:45

+8

澄清Joren的問題:術語_scope_通常指的是變量名稱所在的區域(代碼行)。單詞_scope_通常被誤用爲_lifetime_,就像你所理解的那樣,變量實際上駐留在內存中的時間有多長。 – Thomas 2009-10-31 12:06:55

回答

32

當計算throw表達式時,會從表達式的值中初始化一個異常對象。拋出的異常對象從throw表達式的靜態類型中忽略任何constvolatile限定符。對於類類型,這意味着執行複製初始化

異常對象的作用域超出了引發塊的範圍。可以把它看作是居住在一個特殊的異常區域,在正常調用堆棧的一邊,而本地對象居住的地方。

catch塊中,使用此異常對象初始化使用捕獲的異常對象初始化的名稱,而不是throw的參數,即使這是左值也是如此。

如果你通過非const引用catch,那麼你可以改變異常對象,但不是它初始化的內容。如果您重新拋出異常的方式可能會改變程序的行爲,如果您通過值或常量引用捕獲異常(不包括const_cast)。

當最後一個catch塊沒有通過重新拋出(即無參數拋出表達式求值)完成時,異常對象被銷燬。

4

首先,你拋出的物體幾乎立即就超出了範圍。異常處理程序將捕獲的是原始對象的副本。在捕獲處理程序執行後,該副本將被刪除除非您按值捕獲(不是通過引用)。在這種情況下,將會創建另一個副本。但是你應該通過引用來捕捉它(最好是const一)。

+0

如何根據MFC拋出指向某個東西的指針?您需要考慮問題和答案中隱含的類對象以外的對象。 – Sam 2009-10-31 12:01:18

+0

指針也被複制,但沒有人關心通常:) – vava 2009-10-31 12:10:05

8

異常對象僅在catch塊中可用。您不能在catch塊之外使用異常對象。

try 
{ 
MyException anObject; 
throw anObject; //1 

} 
catch(MyException exObject) 
{ 
} 
  • throw條款(// 1)接收本地對象anObject,並把它作爲一個值參數:當你拋出一個異常和catch以下步驟發生它會創建anObject的副本。
  • catch處理程序捕獲一個MyException對象,它又是一個值參數。此時將創建另一個副本。
  • 如果catch處理程序已經實現以便接收對象(catch (MyException &o))的引用,則避免第二個副本。
  • 如果catch處理程序通過const&接收到異常對象,那麼您只能調用const方法。