C++中的異常處理機制


C++中的捕獲異常機制catch參數中實參的類型不同,采取的處理方式則不相同,且與普通的函數調用還不一樣,具體表現為當拋出異常throw A()或throw obj時,對象會進行一次額外的對象復制操作。

測試類實現如下:

#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;
}

該段代碼執行結果如下:

------ function f1: --------

A(a)

A(a)

exception A b

~A()

~A()

---- 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 -------


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM