问题:如果在main函数中抛出异常会发生什么?
根据我们之前的分析,很容易得出结论。抛出异常嘛,就相当于函数的return。如果我们在main函数中抛出异常的话,不就是直接结束函数了吗?
我们关系的是,我们在main函数抛出的异常被谁接收了,怎么处理的?
示例代码:异常的最终处理?
#include <iostream>
using namespace std;
class Test
{
public:
Test()
{
cout << "Test()";
cout << endl;
}
~Test()
{
cout << "~Test()";
cout << endl;
}
};
int main()
{
static Test t;
throw 1;
cout << "throw end!" << endl;
return 0;
}
在Dev-C++编译器输出如下:
分析:
1. 程序在抛出异常后就停止工作了,并且编译器提示的是“出现问题,程序停止正常工作”的提示窗口。
2. 程序输出为:
Test()
terminate called after throwing an instance of ‘int’
按理来说,我们程序当中只有输出Test() 的代码。并没有输出” terminate called after throwing an instance of ‘int’”的代码。那么这段输出究竟是谁输出的呢?
我们尝试了不同的编译器。虽然输出的信息有异同。但是都是强制结束的程序。通过查阅资料我们可以得知:
1. 如果异常无法被处理,terminate() 结束函数会被自动调用
2. 默认情况下,terminate() 调用库函数abort() 终止程序
3. abort() 函数使得程序执行异常而立即退出
4. C++ 支持替换默认的terminate() 函数实现。
terminate() 函数的替换
自定义一个无返回值无参数的函数
不能抛出任何异常
必须以某种方式结束当前程序调用set_terminate() 设置自定义的结束函数
参数类型为 void(*)()
返回值为默认的terminate()函数入口地址
示例代码:自定义结束函数
#include <iostream>
#include <cstdlib>
#include <exception>
using namespace std;
void my_terminate()
{
cout << "void my_terminate()" << endl;
exit(1);
}
class Test
{
public:
Test()
{
cout << "Test()";
cout << endl;
}
~Test()
{
cout << "~Test()";
cout << endl;
}
};
int main()
{
set_terminate(my_terminate);
static Test t;
throw 1;
return 0;
}
分析:
1. 当terminate() 函数调用 exit() 结束当前程序时,程序会调用析构函数。
2. 当terminate() 函数调用 abort() 结束当前程序时,程序不会调用析构函数。
那么这里就延时出一个问题了。如果当使用exit() 结束当前程序时,我们在析构函数中抛出异常,会发生什么情况?
Test()
void my_terminate()
~Test()
void my_terminate()
调用了两次void my_terminate() 。实际上,abort() 不调用析构函数也是有道理的,就是为了防止程序员在析构函数中抛出异常。