2012-02-22 69 views
1

兩個問題 1)當一個Object /變量被拋出時會發生什麼?舉例來說,當我們拋出一個對象/變量來捕捉時會發生什麼?

int foo() { 
    FILE *fp = ....; 
    int dummy = 10; 
    int *dummy_ptr = new int[10]; 
    throw 1; 
} 

int main() { 
try { 
    foo(); 
} catch (int &i) { 
    std::cout<<"ERROR, the value is "<<i<<std::endl; 
} 
} 

在這種情況下,這裏會發生什麼?一個新的變量,然後傳遞?

如果我用一個指針或變量不參考

像 趕上(INT * I)//或掛鉤(int i)以

此外,沒有所有的變量/資源聲明或啓動範圍內已被釋放/關閉?

2)同樣在重新拋出的情況下,如果我打算重新拋出一個引用,第二個catch得到一個新變量,如果我重新拋出沒有引用(即)的值,那麼在中間擲不受影響....

int goo() { 
    throw 2; 
} 

int foo() { 
    try{ 
     goo(); 
    } catch(int &i) { // (or) catch(int i) // i is not changing in the next line. 
     i = 2; 
     throw; 
    } 
} 

int main() { 
try { 
    foo(); 
} catch (int &i) { 
    std::cout<<"ERROR, the value is "<<i<<std::endl; 
} 
} 

OUTPUT: 捕獲(INT &ⅰ)//輸出2 趕上(int i)以//輸出1

從我的判斷,

我認爲,只要它是參考,價值就會受到影響,如果在中間步驟中它的「按價值傳遞」,價值將會受到影響 。它仍然會將原始對象拋向第二個catch。

(即)爲變量真的不扔中間制動器控制流.....

回答

0

是的,當有異常拋出所有的自動變量都 破壞,拋出的所有封閉範圍,直到 達到處理程序的範圍和。在這個

一個說明, 您在dummy_ptr內存*不會被釋放,一個文件指針fp *不會被關閉。

+0

有道理,但我認爲它沒有道理......因爲,如果在堆/堆棧和東西錯誤之後,什麼是不刪除它的目的?在堆棧它工作正常,但不是在堆.....什麼使堆不同這裏?並且畢竟它是在這裏創建的,而不是從其他地方傳過來的......... – howtechstuffworks 2012-02-22 17:23:13

+0

@howtechstuffworks你在堆上創建東西的原因是因爲你希望它們在你離開函數後繼續存在。 – 2012-02-22 17:31:39

+0

^耶,詹姆斯,多數民衆贊成在一般意義上.......但最新點,如果你的功能失敗......你不想要一切回滾? – howtechstuffworks 2012-02-22 17:34:32

5

在這種情況下,是什麼在這裏發生了什麼?一個新的變量,然後通過?

是的;當你拋出一個對象時,它會在某個地方創建,然後在異常處理完成後銷燬(即,在離開catch塊後不重新拋出)。

如果我使用指針或變量而沒有引用該怎麼辦?此外,在重新拋出的情況下...

如果趕上的價值,那麼你會得到對象的副本 - 如果你重新拋出異常,那麼接下來的處理程序將得到原始的新副本,並且不會看到您可能做出的任何更改。通過引用捕獲將爲您提供拋出的對象的引用 - 如果您重新拋出,則下一個處理程序看到您所做的任何更改。你不能通過指針捕捉對象 - 如果指針被拋出,你只會捕獲一個指針。

此外,範圍內聲明或啓動的所有變量是否已關閉?

當一個異常被拋出所有的自動變量被破壞,在throw的範圍,並達到所有封閉範圍,直到處理程序。動態分配的變量(例如您的new int[10])是而不是已刪除,並且任何清除功能(如fclose)肯定不會被調用爲FILE*變量,除非它們由基於範圍的對象(例如智能指針)管理。

+0

是的在指針的情況下,這就是我的意思,拋出一個指針,我想它會處理,它處理引用相同的方式......現在有道理,沒有通過之前的想法。 – howtechstuffworks 2012-02-22 17:18:13

+0

@howtechstuffworks:投擲指針通常是一個壞主意 - 你當然需要小心它指向什麼。你不應該拋出一個指向自動對象的指針,因爲它可能會在被捕獲之前被銷燬;而且你不應該拋出一個指向新動態對象的指針,因爲如果捕獲器忘記刪除它(如果它以'catch(...)'結尾的話就不能完成)。通常最好拋出一個對象。 – 2012-02-22 17:22:17

+0

「當拋出異常時,所有自動變量被銷燬」正確,但沒有其他東西被銷燬,所以如果問題是由new int [10]分配的內存是否會被釋放,那麼你的「是」應該是「No」 。 – hvd 2012-02-22 17:23:41

0

我不認爲你可以稱之爲一個變量;它沒有名字。但 類型int的新對象被創建,在一個未指定的地方確定 由執行。當你通過引用來捕捉時,引用是綁定到該隱藏對象的 。並且,當您從捕獲物 區塊的末端脫落時,或者通過除了重新拋出 同樣的例外之外的任何方法離開捕獲區塊時,對象是「已釋放」。

相關問題