29、C++ Primer 4th 筆記,異常處理

來源:互聯網
上載者:User

1、類成員的指標不同於指向普通資料或函數的指標,普通指標只根據對象或函數的類型而變化,而成員的指標必須反映成員所屬的類。

2、異常是通過拋出對象而引發的。該對象的類型決定應該啟用哪個處理代碼。被選中的處理代碼是調用鏈中與該物件類型匹配且離拋出異常位置最近的那個。異常以類似於將實參傳遞給函數的方式拋出和捕獲。異常可以是可傳給非引用形參的任意類型的對象,這意味著必須能夠複製該類型的對象。

傳遞數組或函數類型實參的時候,該實參自動轉換為一個指標。被拋出的對象將發生同樣的自動轉換,因此,不存在數組或函數類型的異常。相反,如果拋出一個數組,被拋出的對象轉換為指向數組首元素的指標,類似地,如果拋出一個函數,函數被轉換為指向該函數的指標。

3、一般而言,在處理異常的時候,拋出異常的塊中的局部儲存不存在了。當拋出一個異常的時候,被拋出對象的靜態編譯時間類型將決定異常對象的類型。無論指標所指的對象的實際類型是什麼,異常對象的類型都與指標的靜態類型相匹配。

4、拋出指標通常是個壞主意。

5、尋找匹配catch的過程中,如果找不到,則退出當前函數(釋放當前函數的記憶體並撤銷局部對象),並且繼續在調用函數中尋找。

6、棧展開(stack unwinding):沿嵌套函數調用鏈繼續向上,直至為異常找到一個catch子句。

7、解構函式應該從不拋出異常。在為某個異常進行棧展開的時候,解構函式如果又拋出自己的未處理的另一個異常,將會導致調用標準庫terminate函數。一般而言,terminate函數將調用abort函數,強制從整個程式非正常退出。

8、如果找不到匹配的catch,程式就調用庫函數terminate。

9、在尋找匹配的 catch 期間,找到的 catch 不必是與異常最匹配的那個catch,相反,將選中第一個找到的可以處理該異常的 catch。因此,在 catch 子

句列表中,最特殊的 catch 必須最先出現。

10、除下面幾種可能的區別之外,異常的類型與catch說明符的類型必須完全符合:

• 允許從非 const 到 const 的轉換。也就是說,非 const 對象的 throw可以與指定接受 const 引用的 catch 匹配。

• 允許從衍生類別型型到基類類型的轉換。

• 將數群組轉換為指向數群組類型的指標,將函數轉換為指向函數類型的適當指

針。

    在尋找匹配 catch 的時候,不允許其他轉換。具體而言,既不允許標準算術

轉換,也不允許為類類型定義的轉換。

11、如果catch子句處理因繼承而相關的類型的異常,它就應該將自己的形參定義為引用。

12、空throw語句將重新拋出異常對象,它只能出現在catch或從catch調用的函數中。如果在處理代碼不活動時碰到空 throw,就調用 terminate 函數。

被拋出的異常是原來的異常對象,而不是catch形參。當 catch 形參是基類類型的時候,我們不知道由重新拋出運算式拋出的實際類型,該類型取決於異常對象的動態類型,而不是 catch 形參的靜態類型。例如,來內建基類類型形參 catch的重新拋出,可能實際拋出一個衍生類別型的對象。

    一般而言,catch 可以改變它的形參。在改變它的形參之後,如果 catch 重

新拋出異常,那麼,只有當異常說明符是引用的時候,才會傳播那些改變。

樣本

catch (my_error &eObj) { // specifier is a reference typeeObj.status = severeErr; // modifies the exception objectthrow; // the status member of the exception object is severeErr} catch (other_error eObj) { // specifier is a nonreference typeeObj.status = badErr; // modifies local copy onlythrow; // the status member of the exception rethrown is unchanged}

13、捕獲所有異常

catch(...)

14、在進入建構函式函數體之前處理建構函式初始化式,建構函式函數體內部的catch 子句不能處理在處理建構函式初始化時可能發生的異常。為了處理來自建構函式初始化式的異常,必須將建構函式編寫為函數try塊。可以使用函數測試塊將一組 catch 子句與函數聯成一個整體。

樣本

template <class T> Handle<T>::Handle(T *p)try : ptr(p), use(new size_t(1)){// empty function body} catch(const std::bad_alloc &e){ handle_out_of_memory(e); }

15、exception類型所定義的唯一操作是一個名為what的虛成員,該函數返回const char*對象,它一般返回用來在拋出位置構造異常對象的資訊。

16、異常安全(exception safe)

如果在類的成員函數/或普通函數中申請了記憶體,而在執行函數的中途出現異常,則不會執行程式末尾的釋放記憶體的語句,這會出問題,稱為異常不安全。

所謂異常安全是指,即使發生異常,程式也能正確操作,被分配的任何資源都適當地釋放。

通過定義一個類來封裝資源的分配和釋放,可以保證正確釋放資源,這一技術稱為“資源分派即初始化”,稱為RAII。

樣本

class Resource {public:Resource(parms p): r(allocate(p)) { }~Resource() { release(r); }// also need to define copy and assignmentprivate:resource_type *r; // resource managed by this typeresource_type *allocate(parms p); // allocate this resourcevoid release(resource_type*); // free this resource};

    可能存在異常的程式以及分配資源的程式應該使用類來管理那些資源。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.