70-异常处理深度解析

注:博客中内容主要来自《狄泰软件学院》,博客仅当私人笔记使用。

测试环境:Ubuntu 10.10

GCC版本:9.2.0

 

一、异常处理深度解析

1)问题

                如果在main函数中抛出异常会发生什么?

 

2)如果异常不处理,最后会传到哪里

3)下面的代码输出什么?

 

编程实验
异常的最终处理?
E1-1.cpp
#include 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;
}

操作:g++编译,编译正常。打印结果:
 

Test()
terminate called after throwing an instance of 'int' 
Aborted(core dumped)

 

4)如果异常无法被处理,terminate()结束函数会被自动调用

5)默认情况下,terminate()调用库函数abort()终止程序。

6)abort()函数使得程序执行异常而立即退出

7)C++支持替换默认的terminate()函数实现

8)terminate()函数的替换

    -    自定义一个无返回值无参数的函数

           *不能抛出任何异常

           *必须以某种方式结束当前程序

    -    调用set_terminate()设置自定义的结束函数

           *参数类型为void(*)()

           *返回值为默认的terminate()函数入口地址

编程实验
自定义结束函数
E1-2.cpp
#include 
#include 
#include     //异常处理相关东西using namespace std;void my_terminate()
{cout << "void my_terminate()" << endl;//exit(1);    //确保全局对象和静态局部对象都正常析构abort();
}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)g++编译(使用exit),编译正常。打印结果:

Test()
void my_terminate()
~Test() //来自static Test t的析构函数

2)g++编译(使用abort),编译正常。打印结果:

Test()
void my_terminate()

两个重要知识点
1、main函数里的异常,如果没有没处理,会被一个全局的函数给处理掉。
2、C++编译器之间存在差异(对异常处理已经证明)

 

面试题

            如果析构函数中抛出异常会发生什么情况?

1、析构函数是释放资源的地方,如果抛出异常,导致资源不能正确释放。

2、导致全局结束函数terminate()重复调用,使系统进入不稳定状态。

编程实验
析构函数抛出异常
E1-3.cpp
#include 
#include 
#include using namespace std;void my_terminate()
{cout << "void my_terminate()" << endl;// exit(1);abort();
}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;
}

操作:

1)g++编译正常,打印结果:
 

Test()
void my_terminate()    //解决throw 1
~Test()                //解决throw 1异常时,触发exit(1),然后调用析构函数
void my_terminate()    //抛出异常throw 2,再次触发异常处理函数,打印这个结果

之所以默认调用abort()函数,为了强制终止程序,防止调用析构函数时再次释放资源

 

小结

1)如果异常没有被处理,最后terminate()结束整个程序

2)terminate()是整个程序释放系统资源的最后机会

3)结束函数可以自定义,但不能继续抛出异常

4)析构函数中不能抛出异常,可能导致terminate()多次调用


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部