C++異常的使用,我相信在上文總結的已經比較完整了,本文主要對C++異常這塊進行額外的補充.
即使C++將異常納入標准已經很多年了,但是直到現在都能看到很多堅持不顯式使用異常.(包括本人在內,在寫的代碼中很少使用異常).
在評論異常之前,首先引入google C++ 編碼規范,我們先來看看谷歌怎么看待C++異常.
6. 異常(Exceptions)
不要使用C++異常。
優點:
1)異常允許上層應用決定如何處理在底層嵌套函數中發生的“不可能發生”的失敗,不像出錯代碼的記錄那么模糊費解;
2)應用於其他很多現代語言中,引入異常使得C++與Python、Java及其他與C++相近的語言更加兼容;
3)許多C++第三方庫使用異常,關閉異常將導致難以與之結合;
4)異常是解決構造函數失敗的唯一方案,雖然可以通過工廠函數(factory function)或Init()方法模擬異常,但他們分別需要堆分配或新的“非法”狀態;
5)在測試框架(testing framework)中,異常確實很好用。
缺點:
1)在現有函數中添加throw語句時,必須檢查所有調用處,即使它們至少具有基本的異常安全保護,或者程序正常結束,永遠不可能捕獲該異常。
例如:如果f()依次調用了g()和h(),h拋出被f捕獲的異常,g就要當心了,避免沒有完全清理;
2) 通俗一點說,異常會導致程序控制流(control flow)通過查看代碼無法確定:函數有可能在不確定的地方返回,從而導致代碼管理和調試困難,當然,你可以通過規定何時何地如何使用異常來最小化的降低開銷,卻給開發人員帶來掌握這些規定的負擔;
3)異常安全需要RAII和不同編碼實踐。輕松、正確編寫異常安全代碼需要大量支撐。允許使用異常;
4)加入異常使二進制執行代碼體積變大,增加了編譯時長(或許影響不大),還可能增加地址空間壓力;
5)異常的實用性可能會刺激開發人員在不恰當的時候拋出異常,或者在不安全的地方從異常中恢復,
例如,非法用戶輸入可能導致拋出異常。如果允許使用異常會使得這樣一篇編程風格指南長出很多(譯者注,這個理由有點牽強:-()!
結論:
從表面上看,使用異常利大於弊,尤其是在新項目中,然而,對於現有代碼,引入異常會牽連到所有依賴代碼。
如果允許異常在新項目中使用,在跟以前沒有使用異常的代碼整合時也是一個麻煩。
因為Google現有的大多數C++代碼都沒有異常處理,引入帶有異常處理的新代碼相當困難。
鑒於Google現有代碼不接受異常,在現有代碼中使用異常比在新項目中使用的代價多少要大一點,遷移過程會比較慢,也容易出錯。我們也不相信異常的有效替代方案,如錯誤代碼、斷言等,都是嚴重負擔。
我們並不是基於哲學或道德層面反對使用異常,而是在實踐的基礎上。因為我們希望使用Google上的開源項目,但項目中使用異常會為此帶來不便,因為我們也建議不要在Google上的開源項目中使用異常,如果我們需要把這些項目推倒重來顯然不太現實。
對於Windows代碼來說,這一點有個例外(等到最后一篇吧:D)。
注:對於異常處理,顯然不是短短幾句話能夠說清楚的,以構造函數為例,很多C++書籍上都提到當構造失敗時只有異常可以處理,Google禁止使用異常這一點,僅僅是為了自身的方便,說大了,無非是基於軟件管理成本上,實際使用中還是自己決定。
在這里還有更多對C++異常的討論:https://www.zhihu.com/question/22889420