C++解析-外传篇(1):异常处理深度解析
0.目录
1.异常的最终处理
2.结束函数terminate()
3.小结
1.异常的最终处理
问题:
如果在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;
return 0;
}
运行结果为:
[root@bogon Desktop]# g++ test.cpp
[root@bogon Desktop]# ./a.out
Test()
terminate called after throwing an instance of 'int'
Aborted (core dumped)
(不同编译器的运行结果不同。)
2.结束函数terminate()
- 如果异常无法被处理,terminate() 结束函数会被自动调用
- 默认情况下,terminate() 调用库函数 abort() 终止程序
- abort() 函数使得程序执行异常而立即退出
- C++支持替换默认的 terminate() 函数实现
terminate() 函数的替换:
- 自定义一个无返回值无参数的函数
- 不能抛出任何异常
- 必须以某种方式结束当前程序
- 调用 set_terminate() 设置自定义的结束函数
- 参数类型为
void (*) ()
- 返回值为默认的 terminate() 函数入口地址
- 参数类型为
示例1——自定义结束函数:
#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;
}
运行结果为:
[root@bogon Desktop]# g++ test.cpp
[root@bogon Desktop]# ./a.out
Test()
void my_terminate()
~Test()
将exit(1);
改为abort();
后的运行结果:
示例2——自定义结束函数:
void my_terminate()
{
cout << "void my_terminate()" << endl;
// exit(1);
abort();
}
运行结果为:
[root@bogon Desktop]# g++ test.cpp
[root@bogon Desktop]# ./a.out
Test()
void my_terminate()
Aborted (core dumped)
(abort()函数是异常终止一个程序,并且异常终止的时候不会调用任何对象的析构函数。如果调用的是exit()函数,那么会确保所有的全局对象和静态局部对象的析构函数被调用。)
面试题:
如果析构函数中抛出异常会发生什么情况?
示例——析构函数抛出异常:
#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;
throw 2;
}
};
int main()
{
set_terminate(my_terminate);
static Test t;
throw 1;
return 0;
}
运行结果为:
[root@bogon Desktop]# g++ test.cpp
[root@bogon Desktop]# ./a.out
Test()
void my_terminate()
~Test()
Aborted (core dumped)
(析构函数中不能抛出异常,可能导致 terminate() 多次调用)
(不同编译器之间在默认的 terminate() 函数实现上有差异。)
3.小结
- 如果异常没有被处理,最后 terminate() 结束整个程序
- terminate() 是整个程序释放系统资源的最后机会
- 结束函数可以自定义,但不能继续抛出异常
- 析构函数中不能抛出异常,可能导致 terminate() 多次调用