C++解析-外传篇(1):异常处理深度解析

本文深入探讨了C++中异常未被处理时的行为,详细解释了terminate()函数的作用及如何自定义其行为,同时讨论了析构函数中抛出异常的后果。

0.目录

1.异常的最终处理
2.结束函数terminate()
3.小结

1.异常的最终处理

问题:
如果在main函数中抛出异常会发生什么?
如果异常不处理,最后会传到哪里
1250397-20181211155906223-1891069808.png

下面的代码的输出什么?
1250397-20181211155926396-703255412.png

示例——异常的最终处理?:

#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() 函数的替换:

  • 自定义一个无返回值无参数的函数
    1. 不能抛出任何异常
    2. 必须以某种方式结束当前程序
  • 调用 set_terminate() 设置自定义的结束函数
    1. 参数类型为 void (*) ()
    2. 返回值为默认的 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() 多次调用

转载于:https://www.cnblogs.com/PyLearn/p/10103115.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值