C++中的異常處理機制

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 -------
相關文章
相關標籤/搜索