2010-03-26 67 views
67

可能重複:
catch exception by pointer in C++C++ catch塊 - 通過值或引用捕獲異常?

我總是通過值捕獲異常。例如

try{ 
... 
} 
catch(CustomException e){ 
... 
} 

但我碰到一些代碼,而不是catch(CustomException &e)。這是a)罰款b)錯誤c)灰色地帶?

+0

請注意,正確的引用也是常量:'catch(CustomException const&e)'... – 2015-02-07 01:27:15

+1

不應該被標記爲重複 - 捕獲ptr的例外與通過引用或值捕獲不同。 – wcochran 2017-02-10 20:23:31

回答

103

在C++異常標準的做法是...

投擲的價值,漁獲參考

通過值捕獲在繼承層次面對的問題。假設您的示例中有另一個類型MyException,它繼承自CustomException,並覆蓋像錯誤代碼這樣的項目。如果MyException類型被拋出,您的catch塊將導致它被轉換爲CustomException實例,這將導致錯誤代碼發生變化。

參考

+4

爲此,我會補充:通過const引用趕上。不幸的是,你可以拋出一個const對象,並用非const引用來捕獲它。爲了避免這種無聲的「拋棄」const,總是捕獲一個const引用,並確保你的異常類型具有const正確的訪問器。 – 2010-03-26 10:01:13

+20

@Danial Earwicker:爲什麼「不幸」你可以通過非const引用捕獲? 異常對象總是被複制,所以無論你拋出什麼'對象',你都不能影響任何catch塊中的原始對象,因爲拋出的'object'實際上只是一個初始化器。 const沒有拋棄const;異常對象總是非常量的,非易失性的。通過非const引用允許捕獲使中間catch塊能夠將信息添加到異常。它不常用,但如果你需要的話,它就在那裏。 – 2010-03-26 10:06:38

+0

你可以提供一個參考,如果你想接受的答案:) – 2010-03-26 10:07:12

20

按值捕獲將分片如果異常是派生類型的異常對象,您捕獲的類型。

這可能或可能不會影響你的catch塊的邏輯,但沒有什麼理由不被const引用捕獲。

請注意,如果throw;在catch塊中沒有參數,則無論是否捕獲切片副本或對異常對象的引用,都會重新生成原始異常。

+6

在這種情況下,我不熟悉術語* slice *。 – 2012-11-27 16:59:49

+6

我認爲「切片」是一個用來引用傳遞語言的人喜歡使用的術語。如果你將派生對象賦值給它的基類型,這個想法是「切斷」對象的一部分,對我來說這似乎是一種誤導性的方式,因爲實際發生的事情是,在基類的複製賦值運算符「 base&operator =(const base&other)'派生對象被隱式轉換爲'base&'引用,所以賦值將派生類視爲基類。有沒有魔術切片或轉移的東西,你正在調用一個函數 – Injektilo 2013-05-16 08:30:31

8

除非你想用異常不甘示弱,你通常應該使用const引用:catch (const CustomException& e) { ... }。編譯器處理拋出的對象的生命週期。

2

(CustomException e) CustomException的新對象被創建...所以它的構造函數將被調用,而在(CustomException & e)它只會引用...不創建新對象並且不會調用構造函數...所以正式的是一點點的開銷......後來更好用...