如何編寫異常代碼?比如處理bad-alloc的時候,是不是應該先銷毀當前資源?
rt
20160316 Rule of three 這篇 wiki 總結得不錯:Rule of three (C++ programming)201603211337 C++: RAII without exceptions
----
如果你所有的變數類型都是容器那就沒關係,譬如vector/shared_ptr等,構造shared_ptr一定要用make_shared而不是new,這種時候你什麼都不用管。如果不是的話,那你就寫代碼模擬容器的行為。
其實也沒那麼複雜的,誰讓你們老是用裸指針對於某種異常,要麼別處理直接讓程序崩潰掉
如果處理的話,要保證程序能回到拋異常之前的狀態,如果不能保證,就不能處理這個異常
就比如拷貝構造,你從源拷貝到目標的時候,如果出了異常,就要先catch,然後倒著把已經拷貝的東西析構掉,再throw,這樣就能保證如果用戶在最外面catch了異常,程序能恢復到拷貝操作之前的狀態,沒有內存泄漏
那些說處理方式不好的,是你們自己管理內存水平太差了吧,現在C++的異常處理已經不會給不拋異常的情況增加巨大的運行時消耗了,不然STL到處都有異常,怎麼沒見有人抱怨STL慢簡單的情況用常識,複雜的情況你也沒辦法。
異常情況下,是沒有處理資源回滾的通解的。只有兩個特例有解:- 資源之間沒有依賴關係。這時候用 RAII。但是實際工程中資源之間不可能沒有依賴關係。
- 有支持 two-phase commit 的事務系統。比如 RDBMS。
告訴你四字箴言: RAII
C++的異常處理方式不好, 所以throw/catch式的語句盡量少寫, 實在有需求, 乾脆就設計一個專門的異常處理模塊, 然後直接調用函數處理. 簡而言之就是用C的辦法處理.
前腳回答完, 後腳就有人說事, 所以經常匿名答題.
管理內存的水平這個事情, 跟throw/catch式有關係嗎? 而且資源管理僅僅是內存管理嗎? 對於大多數系統應用, 內存管理是重頭沒錯, 不過題主自己沒說, 我不能這麼假設.
STL的異常, 是為了保證通用性, 因為throw你不catch等於沒有, 但是你catch但是STL不throw那有人就要罵了, 就這麼簡單. STL的東西你要寫到業務代碼裡面去? 你可以試試...
沒有開銷就實用嗎? 宏編程, 模板元, 不僅僅沒有開銷, 還能夠編譯時優化, 你看有很多人用嗎?
對題主說明一下, C++程序員有時候也是會寫throw/catch的, 在很有空的時候....
舉個簡單例子吧, IPC, 一個鎖. 用容器包裹好了, 問題是, 程序崩潰之前, 我是要解鎖還是不解鎖? 很多時候這個要看情況的, 那好吧, 我在容器裡面加一些log信息, 根據需求析構, 等等, 那更新log有沒有overhead? (其實多數系統應用這樣做也無所謂的, 我們假設有性能需求) 要減小這個overhead, 可以寫一個檢查狀態的函數, 先catch, 再檢查, 然後再根據情況指導鎖的析構. 所以你的catch裡面寫的就是一個檢查然後指導析構的函數.... 這跟直接檢查返回值/指針, 然後調用函數, 有區別嗎? 注意catch是可以寫在各個層次, 而且不管阿貓阿狗寫的thow它都會捕捉的....
推薦閱讀:
※c++ 在使用vector::push_back時是否需要使用try...catch...包裹起來?
※C++ 需要 restrict 關鍵字嗎?
※在校學生深入學習QT後會不會找不到比較好的工作?
※面試 C++ 被人問你是如何優化你的代碼的,該從哪些方面進行回答?
※為什麼 C++ 標準不明確二進位介面 (ABI) 標準?