为什么会出现这样的结果呢?,当我们抛出一个异常的时候,异常会随着函数调用关系,一级一级向上抛出,直到被捕获才会停止,如果最终没有被捕获将会导致调用terminate函数,上面的输出就是自动调用terminate函数导致的,为了保证更大的灵活性,C++提供了set_terminate函数可以用来设置自己的terminate函数.设置完成后,抛出的异常如果没有被捕获就会被自定义的terminate函数进行处理.下面是一个使用的例子:
#include
#include
#include
using namespace std;
class MyError {
const char* const data;
public:
MyError(const char* const msg = 0):data(msg)
{
//idle
}
};
void do_error() {
throw MyError("something bad happend");
}
//自定义的terminate函数,函数原型需要一致
void terminator()
{
cout << "I'll be back" << endl;
exit(0);
}
int main()
{
//设置自定义的terminate,返回的是原有的terminate函数指针
void (*old_terminate)() = set_terminate(terminator);
do_error();
}
上面的代码会输出I'll be back
到此为此关于异常匹配的我所知道的知识点都已经介绍完毕了,那么接着可以看看下一个话题,异常中的资源清理.
异常中的资源清理
在谈到局部跳转的时候,说到局部调转不会调用对象的析构函数,会导致内存泄露的问题,C++中的异常则不会有这个问题,C++中通过堆栈反解将已经定义的对象进行析构,但是有一个例外就是构造函数中如果出现了异常,那么这会导致已经分配的资源无法回收,下面是一个构造函数抛出异常的例子:
#include
#include
using namespace std;
class base
{
public:
base()
{
cout << "I start to construct" << endl;
if (count == 3) //构造第四个的时候抛出异常
throw string("I am a error");
count++;
}
~base()
{
cout << "I will destruct " << endl;
}
private:
static int count;
};
int base::count = 0;
int main()
{
try{
base test[5];
} catch(...){
cout << "catch some error" << endl;
}
}
上面的代码输出结果是:
I start to construct
I start to construct
I start to construct
I start to construct
I will destruct
I will destruct
I will destruct
catch some error
在上面的代码中构造函数发生了异常,导致对应的析构函数没有执行,因此实际编程过程中应该避免在构造函数中抛出异常,如果没有办法避免,那么一定要在构造函数中对其进行捕获进行处理.最后介绍一个知识点就是函数try语句块,如果main函数可能会抛出异常该怎么捕获?,如果构造函数中的初始化列表可能会抛出异常该怎么捕获?下面的两个例子说明了函数try语句块的用法:










