C++中的异常处理机制

时间:2022-08-10 15:07:22

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