C++ 及 Windows 的異常處理(try catch; __try __except; __try __finally)

來源:互聯網
上載者:User
  • C++ 異常處理:try,catch
try{    // 可能出錯的語句, 如果有錯,就 throw ...    // 初始化一個異常對象(exception object)}catch( 類型名 [形參名] )    // 異常說明符(exception specifier){    // do 異常處理}catch( 類型名 [形參名] ){    // do 異常處理}

C++ 的異常處理很簡單,就是如上的三個關鍵字,注意 C++ 中 throw,catch 之後沒有 Java 等語言中的 finally。

Q: 為何C++不提供“finally”結構? 
A: 因為C++提供了另一種機制,完全可以取代finally,而且這種機制幾乎總要比finally工作得更好:“分配資源即初始化”。
(見《The C++ Programming Language》14.4節)基本的想法是,用一個局部對象來封裝一個資源,這樣一來局部對象的解構函式就可以自動釋放資源。這樣,程式員就不會“忘記釋放資源”了。

  • Windows SEH 異常處理:__try, __except

它們是 Windows 系列作業系統平台上提供的 SEH 模型,也就是說在 C++ 中調用的時候,其實是調用 Windows 的 API。
SEH,又稱結構化異常處理,是設計 Windows 作業系統時提出一個種處理異常的方法。這組異常處理機制和 C++ 的很相像,只是關鍵字是 except 而不是catch。

catch 和 except 的一點不同: 
catch 關鍵字後面往往好像接受一個函數參數一樣,可以是各種類型的異常資料對象;但是 __except 關鍵字則不同,它後面跟的卻是一個運算式(可以是各種類型的運算式)。

小結

(1) C++ 異常模型用 try catch 文法定義,而 SEH 異常模型則用 __try __except 文法;
(2) 與 C++ 異常模型相似,__try __except 也支援多層的 __try __except 嵌套。
(3) 與 C++ 異常模型不同的是,__try __except 模型中,一個 __try 塊只能是有一個 __except 塊;而 C++ 異常模型中,一個 try 塊可以有多個 catch 塊。
(4) 與 C++ 異常模型相似,__try __except 模型中,尋找搜尋異常模組的規則也是逐級向上進行的。但是稍有區別的是,C++ 異常模型是按照異常對象的類型來進行匹配尋找的;而 __try __except 模型則不同,它通過一個運算式的值來進行判斷。如果運算式的值為1(EXCEPTION_EXECUTE_HANDLER),表示找到了異常處理模組;如果值為0(EXCEPTION_CONTINUE_SEARCH),表示繼續向上一層的 __try __except 域中繼續尋找其它可能匹配的異常處理模組;如果值為-1(EXCEPTION_CONTINUE_EXECUTION),表示忽略這個異常,注意這個值一般很少用,因為它很容易導致程式難以預測的結果,例如,死迴圈,甚至導致程式的崩潰等。
(5) __except 關鍵字後面跟的運算式,它可以是各種類型的運算式,例如,它可以是一個函數調用,或是一個條件運算式,或是一個逗號運算式,或乾脆就是一個整型常量等等。最常用的是一個函數運算式,並且通過利用 GetExceptionCode() 或 GetExceptionInformation() 函數來擷取當前的異常錯誤資訊,便於程式員有效控制異常錯誤的分類處理。
(6) SEH 異常處理模型中,異常被劃分為兩大類:系統異常和軟體異常。其中軟體異常通過 RaiseException() 函數拋出。RaiseException( )函數的作用類似於 C++ 異常模型中的 throw 語句。

詳細的請參看:http://www.cnblogs.com/wenziqi/archive/2010/08/26/1809074.html

  • Windows SEH 異常處理:__try, __finally

__try __finally 語句的文法與 __try __except 很類似,稍有不同的是,__finally 後面沒有一個運算式,這是因為 __try __finally 語句的作用不是用於異常處理,所以它不需要一個運算式來判斷當前異常錯誤的種類。另外,與 __try __except 語句類似,__try __finally 也可以是多層嵌套的,並且一個函數內可以有多個 __try __finally 語句,不管它是嵌套的,或是平行的。當然,__try __finally 多層嵌套也可以是跨函數的。

最關鍵的一點:“不管在何種情況下,在離開當前的範圍時,__finally 塊地區內的代碼都將會被執行到”。

小結

__finally 塊被執行的流程時,無外乎三種情況:

(1) 順序執行到 __finally 塊地區內的代碼,這種情況很簡單,容易理解;
(2) goto 語句或 return 語句引發的程式控制流程離開當前 __try 塊範圍時,系統自動完成對 __finally 塊代碼的調用;
(3) 由於在 __try 塊中出現異常時,導致程式控制流程離開當前 __try 塊範圍,這種情況下也是由系統自動完成對 __finally 塊的調用。

無論是第 2 種,還是第 3 種情況,毫無疑問,它們都會引起很大的系統開銷,編譯器在編譯此類程式碼時,它會為這兩種情況準備很多的額外代碼。
一般第 2 種情況,被稱為“局部展開(LocalUnwinding)”;第3種情況,被稱為“全域展開(GlobalUnwinding)”。
第 3 種情況,也即由於出現異常而導致的“全域展開”,對於程式員而言,這也許是無法避免的,因為在利用異常處理機制提高程式可靠健壯性的同時,不可避免的會引起效能上其它的一些開銷。有得必有失。

備忘:本文轉載自:http://www.cppblog.com/yehao/articles/165099.html

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.