2010-09-08 61 views
2

我一個代碼庫正與一幫開發商誰不主要是計算機科學和軟件工程(主要計算機工程)何時以及如何捕獲異常

我找了一個很好的文章時左右應該發現異常,並且應該嘗試從中恢復。我前段時間發現了一篇文章,認爲我解釋得很好,但谷歌並沒有幫我找到答案。

我們正在用C++進行開發。文章鏈接是可接受的答案形式,正如帶指針的摘要一樣。我想在這裏教,所以教程格式會很好。至於那些寫入非軟件工程師可訪問的內容。謝謝。

+0

前段時間我們討論了異常:http://stackoverflow.com/questions/1744070/why-should-exceptions-be-used-conservatively – 2010-09-08 14:38:59

+2

捕捉異常只是編寫優秀且強大的C++代碼的一部分。你認爲你和你的同事能夠很好地掌握編寫異常安全的代碼嗎,或者你還需要參考嗎? – 2010-09-08 14:43:36

+0

離開了一段時間,對於延遲抱歉。我認爲我對編寫異常安全代碼有合理的把握,但與我的同事不太一樣,所以對此的參考也將不勝感激。 – BitShifter 2010-09-28 23:06:59

回答

5

香草薩特有一個excellent article這可能對你有用。它沒有回答你的具體問題(何時/如何捕捉),但是提供了處理異常情況的總體概述和指導。

我抄他在這裏的總結逐字

錯誤和 nonerrors區分。失敗是一個錯誤,如果 且僅當它違反了函數的 能力,以滿足其被調用者 前提條件,建立了自己的 後置條件,或者重新建立一個 不變的這股責任 維護。其他一切都不是 錯誤。

確保錯誤始終使您的 程序處於有效狀態;這是 的基本保證。謹防 不變破壞錯誤 (包括但不限於 泄漏),這只是簡單的錯誤。

寧可另外保證 任一最終狀態或者是 原來的狀態(如果有一個誤差, 操作被回滾)或 預定目標狀態(如果沒有 錯誤時,操作提交); 這是有力的保證。

另外保證 的操作永遠不會失敗。雖然 這對於大多數 功能來說都是不可能的,但它是 函數(如析構函數和 )的重新分配函數所必需的。

最後,寧願使用例外 代替錯誤代碼來報告 錯誤。使用錯誤代碼,只有當 例外,不能使用(當你 不控制所有可能的調用 代碼,並不能保證它會被 用C++編寫和編譯使用 相同的編譯器和兼容編譯 選項),和條件是 沒有錯誤。

+0

一如既往,我喜歡Sutter的風格,他的建議很有聲音。但是,我擔心「更喜歡使用例外而不是錯誤代碼」可能會被誤解。這不是例外說,每一個「事故」應報告爲異常的道歉,這意味着,如果你有返回錯誤代碼或拋出異常之間作出選擇,你應該拋出。我自己對此不太確定。 – 2010-09-08 15:22:46

+1

錯誤代碼有它們的位置(不要用異常替換所有的東西,因爲你可以(只是在合適的地方))。例如:只要錯誤代碼不會暴露給類的用戶,就可以在類中使用私有方法之間的錯誤代碼。 – 2010-09-08 18:21:07

0

章 「異常處理」 可能是this MSDN節將幫助你......

0

最簡單的建議:

如果你不知道是否捕捉到異常,不要捕捉它,讓它流動,有人會在一個點上。

關於例外的一點是它們是例外(認爲是std::bad_alloc)。除了一些奇怪的用於深度嵌套代碼塊(我不太喜歡)的「快速退出」外,只有當你碰巧發表了一些你不知道如何處理的東西時,才應該使用異常。

讓我們挑的例子:

file = open('littlefile.txt', open.mode.Read) 

它似乎是顯而易見的,對我來說,這可能會失敗,並在若干條件。雖然報告失敗的原因很重要(對於準確的診斷),但我發現在這裏拋出異常並不是好習慣。

在C++中我會寫這樣的功能:

boost::variant<FileHandle,Error> open(std::string const& name, mode_t mode); 

功能可以要麼返回的文件句柄(大)或錯誤(oups)。但既然它是預期的,現在更好地處理它。此外它具有明確的優勢,看着簽名意味着你知道該期待什麼(而不是在討論異常規範,這是一個破碎的功能)。

一般來說,我傾向於將這些函數看作find函數。當你搜索某些東西時,預計搜索可能會失敗,這裏沒有什麼特別的。

想想關聯容器的一般情形:

template <typename Key, typename Value> 
boost::optional<Value const&> Associative::GetItem(Key const& key) const; 

再次感謝提振,我說清楚,我的方法可能(或不會)返回預期值。不需要拋出ElementNotFound異常。

又如:用戶輸入驗證有望失敗。一般來說,投入預計會是敵對的/不健康的/錯誤的。這裏不需要例外。

另一方面,假設我的軟件處理數據庫,如果沒有它,就不可能運行。如果數據庫抽象層失去與數據庫的連接並且無法建立新的連接,那麼引發異常是有意義的。

我保留例外的技術問題(連接丟失,內存不足等...)。