异常——异常处理深度解析

问题:如果在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() 函数实现。

  1. 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() 不调用析构函数也是有道理的,就是为了防止程序员在析构函数中抛出异常。

猜你喜欢

转载自blog.csdn.net/small_prince_/article/details/80560964