1. 程式人生 > >C++ Primer 第五章筆記

C++ Primer 第五章筆記

Chapter 5 Statements

5.6 try 語句塊和異常處理

異常是指存在於執行時的反常行為,這些行為超出了函式正常功能的範圍。異常處理包括:

  • throw 表示式(throw expression),異常檢測部分使用 throw 表示式來表示它遇到了無法處理的問題。我們說 throw 引發(raise)了異常。

  • try 語句塊(try block),異常處理部分使用 try 語句塊處理異常。try 語句塊以關鍵字 try 開始,並以一個或多個 catch 子句(catch clause)結束。try 語句塊中程式碼丟擲的異常通常會被某個 catch 子句處理。因為 catch 子句 “處理” 異常,所以它們也被稱作異常處理程式碼(exception handler)

  • 一套異常類(exception class),用於在 throw 表示式和相關的 catch 子句之間傳遞異常的具體資訊。

5.6.1 throw 表示式

​ 程式的異常檢測部分使用 throw 表示式引發一個異常。throw 表示式包含關鍵字 throw 和緊隨其後的一個表示式,其中表達式的型別就是丟擲異常的型別。throw 表示式後面通常緊跟一個分號,從而構成一條表示式語句。

​ 在真實的程式中,應該把物件相加的程式碼和使用者互動的程式碼分離開來。

5.6.2 try 語句塊

​ try 語句塊的通用語法形式是

try {
    program-statements
} catch (
exception-declaration) { handler-statements } catch (exception-declaration) { handler-statements } // ...

​ 跟在 try 語句塊中的 program-statements 組成程式的正常邏輯,像其他任何塊一樣,program-statements 可以有包括宣告在內的任意 C++ 語句。一如往常,try 語句快內宣告的變數在塊外部無法訪問,特別是在 catch 子句內也無法訪問。

​ 複雜系統中,程式在遇到丟擲異常的程式碼前,其執行路徑可能已經經過了多個 try 語句塊。例如,一個 try 語句塊可能呼叫了包含另一個 try 語句塊的函式,新的 try 語句塊可能呼叫了包含又一個 try 語句塊的新函式,以此類推。

​ 尋找處理程式碼的過程與函式呼叫鏈剛好相反。當異常被丟擲時,首先搜尋丟擲該異常的函式。如果沒有找到匹配的 catch 子句,終止該函式,並在呼叫該函式的函式中繼續尋找。如果還是沒有找到匹配的 catch 子句,這個新的函式也被終止,繼續搜尋呼叫它的函式。以此類推,沿著程式的執行路徑逐層回退,直到找到適當型別的 catch 子句為止。

​ 如果最終還是沒能找到任何匹配的 catch 子句,程式轉到名為 terminate 的標準函式庫函式。該函式的行為與系統有關,一般情況下,執行該函式將導致程式非正常退出。

​ 對於那些沒有任何 try 語句塊定義的異常,也按照類似的方式處理:畢竟,沒有 try 語句塊也就意味著沒有匹配的 catch 子句。如果一段程式沒有 try 語句塊且發生了異常,系統會呼叫 terminate 函式並終止當前程式的執行。

5.6.3 標準異常

​ C++ 標準庫定義了一組類,用於報告標準庫函式遇到的問題。這些異常也可以在使用者編寫的程式中使用,它們分別定義在 4 個頭檔案中:

  • exception 標頭檔案定義了最通用的異常類 exception。它只報告異常的發生,不提供任何額外資訊。
  • stdexcept 標頭檔案定義了幾種常用的異常類,見表 5.1。
  • new 標頭檔案定義了 bad_alloc 異常型別。
  • type_info 標頭檔案定義了 bad_cast 異常型別。

15

​ 標準庫異常類只定義了集中運算,包括建立或拷貝異常型別的物件,以及為異常型別的物件賦值。我們只能以預設初始化的方式初始化 exception、bad_alloc 和 bad_cast 物件,不允許為它們提供初始值。

​ 其他異常型別的行為則恰好相反:應該使用 string 物件或者 C 風格字串初始化這些型別的物件,但是不允許使用預設初始化的方式。當建立此類物件時,必須提供初始值,該初始值包含有錯誤相關的資訊。

​ 異常型別只定義了一個名為 what 的成員函式,該函式沒有任何引數,返回值是一個指向 C 字串的 const char*。該字串的目的是提供關於異常的一些文字資訊。

​ what 函式返回的 C 風格字串的內容與其他異常物件的型別有關。如果異常型別有一個字串初始值,則 what 返回該字串。對於其他無初始值的異常型別來說,what 返回的內容也由編譯器決定。