C++中的捕獲異常機制catch參數中實參的類型不一樣,採起的處理方式則不相同,且與普通的函數調用還不同,具體表現爲當拋出異常throw A()或throw obj時,對象會進行一次額外的對象複製操做。ios
測試類實現以下:函數
#include <iostream> /** * 測試異常拋出與虛函數 */ using namespace std; class A { public: A() {cout << "A() " << endl;} ~A(){cout << "~A()" << endl;} A(const A& a){cout << "A(a)" << endl;} virtual void func(){cout << "A::func()" << endl;} }; class B:public A { B() {cout << "B()" << endl;} B(const B &b) {cout << "B(b)" << endl;} ~B(){cout << "~B()" << endl;} virtual void func() {cout << "B::func()" << endl;} };
1) 當採用對象傳遞方式捕獲異常時,在對象中會發生兩次複製操做,一次爲對象a複製給臨時對象,二次爲臨時對象經過引用方式傳遞給實參b。測試
void f1(const A &a) { try { cout << "------ function f1: --------" << endl; throw a; } catch( A b) { cout << "exception A b" << endl; } cout << "---- function f1 -------" << endl; }
該段代碼執行結果以下:spa
------ function f1: --------對象
A(a)blog
A(a)繼承
exception A bit
~A()io
~A()function
---- function f1 -------
2) 當採用引用方式捕獲異常時,就會少了上面第二次的複製開銷,即生成臨時對象直接做爲參數傳遞。
void f2(const A &a) { try { cout << "------ function f2: --------" << endl; throw a; } catch( const A &b) { cout << "exception A &b" << endl; } cout << "---- function f2 -------" << endl; }
執行結果以下:
------ function f2: -------- A(a) exception A &b ~A() ---- function f2 -------
3) 若是直接拋出引用對象,系統會報錯,由於異常處理機制不侷限於當前函數,有可能在該函數以外。
void f3(const A &a) { try { cout << "------ function f3: --------" << endl; throw &a;//引用異常,系統會意外終止 } catch(const A &b) { cout << "exception A &b" << endl; } cout << "---- function f3 -------" << endl; }
4) 拋出異常時,可直接拋出對象,也可生成一個對象,不一樣的是這樣會顯式調用構造函數非複製構造函數。
void f4(const A &a) { try { cout << "------ function f4: --------" << endl; throw A(); } catch(const A &b) { cout << "exception A &b" << endl; } cout << "---- function f4 -------" << endl; }
執行結果以下:
------ function f4: -------- A() exception A &b ~A() ---- function f4 -------
5) 在處理帶有繼承的異常類時,異常處理規則不是按照虛函數繼承中」最優匹配(best fit)」原則,而是」最早匹配(first fit)」原則進行處理。
void f5(const B& b) { try { cout << "------ function f5: --------" << endl; throw b; } catch(const A &a) { cout << "exception A &a" << endl; } catch(const B &b1) { cout << "exception B &b1" << endl; } cout << "---- function f5 -------" << endl; }
該異常會匹配A而非B:
------ function f5: -------- A() B(b) exception A &a ~B() ~A() ---- function f5 -------