如果在main()函数中抛出异常会发生什么?
#include <iostream>
class Test
{
public:
Test()
{
cout << "Test()";
cout << endl;
}
~Test()
{
cout << "~Test()";
cout << endl;
}
};
int main()
{
static Test t;
throw 1;
return 0;
}
如果异常无法被处理,terminate()结束函数会被自动调用,默认情况下,terminate()调用库函数abort()终止程序,abort()函数使得程序执行异常而立即退出,c++支持替换默认的terminate()函数实现(可以自定义结束函数终止异常)。
terminate()函数的替换:
自定义一个无返回值参数的函数,不能抛出任何异常,必须以某种方式结束当前程序。
调用set_terminate()设置自定义的结束函数:参数类型为void(*)(),返回值默认的terminate()函数入口地址。
#include <iostream>
#include <cstdlib>
#include <exception>//c++标准库中的,与异常有关
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); //调用my_terminate
static Test t;
throw 1;
return 0;
}
面试题:如果析构函数中抛出异常会发生什么?
第一个析构函数是用于释放资源的地方,如果抛出异常,有可能导致资源得不到正确的释放。第二点是有可能导致全局的结束函数terminate被重复的调用,这是极其可怕的,有可能使系统进入不稳定状态。
#include <iostream>
#include <cstdlib>
#include <exception>
using namespace std;
void my_terminate()
{
cout << "void my_terminate()" << endl;
// exit(1); //调用 set_terminate(my_terminate);,
abort(); //默认为这个如果是上边的,可能析构函数抛出异常,重复删除。调用abort之前可能打印字符串或者弹出个窗口
}
class Test
{
public:
Test()
{
cout << "Test()";
cout << endl;
}
~Test()
{
cout << "~Test()";
cout << endl;
throw 2; //调用 set_terminate(my_terminate);
}
};
int main()
{
set_terminate(my_terminate);
static Test t;
throw 1; //开始调用 set_terminate(my_terminate);
return 0;
}
terminate()是整个程序释放系统资源的最后机会。结束函数可以自定义,但不能继续抛出异常,析构函数中不能抛出异常,可能导致terminate()多次调用。