下面是C++編程一個不太常見的問題:如何避免由於意外異常導致的問題?
程序員寫了一個C++庫(我們叫它美孚),其中包括程序員B的程序調用的方法,一個漂亮的公共API,以實施他的計劃的一部分。在使用Foo API時,程序員B會查看文檔和頭文件,但不會在.cpp文件中使用,主要是因爲擁有公共API的全部要點是隱藏實現細節。程序員B讓他的程序工作,最初一切看起來都很好。
一天的程序是做它的事,當一些不尋常的美孚代碼庫,導致一個Foo方法拋出異常發生裏面。程序員B不知道那種類型的異常可能會被Foo方法拋出,所以這個異常不會被捕獲(並且程序崩潰),或者異常被一個非常普通的異常處理程序捕獲(例如catch()。 ..))並沒有得到充分的處理(所以程序做了一些非最優化的事情,比如用一個神祕的錯誤信息來建立一個對話框)。
因爲我想我的C++軟件是強大的,我的問題是,什麼是避免像上述方案中的好方法嗎?要求程序員B讀取Foo代碼庫中的所有.cpp文件(以及Foo調用的任何C++代碼庫的所有.cpp文件,以此類推),尋找throw語句似乎不是一個合適的解決方案,因爲它違背了封裝的精神,即使這樣做,也不能保證將來可能不會添加更多的投擲語句。要求程序員A記錄所有可能拋出的異常似乎是一個好主意,但實際上程序員A很可能會錯過其中的一些,特別是如果他的代碼又調用另一個庫,可能或不可能記錄其中的100%可能的例外。
在Java中,有一些支持自動化的異常處理檢查;例如你可以註釋你的Java方法來聲明它們可能拋出什麼異常,如果調用的代碼沒有明確地處理所有這些異常(或者它本身聲明它可能會拋出異常),那麼編譯失敗,程序員被迫修復它程序 - 從而防止上述的問題情況。另一方面,C++沒有這樣的編譯時執行,這意味着驗證C++程序正確處理所有異常似乎完全取決於程序員和QA團隊。但是在一個非平凡的程序中,實際執行這種驗證似乎不切實際;有沒有一些技術(自動化或非自動化),C++程序員可以通過這些技術獲得他們的程序以一種被認爲的方式處理所有可能拋出的異常的信心? (哪怕只是一個程序,它會列出所有可以從不同的調用拋出的異常的將是有益的,我覺得 - 至少那麼會是已知的可能性列表要檢查的異常處理代碼)
請注意,Java異常註釋不適用於所有異常。例如,它們不適用於NullPointerExceptions,因爲這需要將每個解引用包含在try/catch塊中,這將非常繁瑣,以至於任何人都不會使用Java。 – immibis 2015-04-02 06:33:16
在代碼的某個位置用'catch(...)'嘗試'',這樣至少可以在出現這種情況時正常退出。如果你希望能夠從中恢復,那麼你需要在每次調用之後用包含'catch(...)'的代碼包裝B的API,並做適當的事情;然而,很難說什麼是「合適的」,因爲問題的本質是代碼的「B」部分可能是不可恢復的。 – 2015-04-02 07:10:10
我想你的問題在第一段之後會切換「A」和「B」。我使用'B'作爲圖書館作者和'A'作爲使用圖書館的人並且接收到意外的異常。 – 2015-04-02 07:11:09