71课 外传篇1、异常处理深度解析

本文探讨了C++中异常处理机制,包括mian函数中抛出异常的处理、自定义异常终结函数的方法及其注意事项,以及析构函数中抛出异常的影响。

1、mian函数中抛异常

/*************        异常的最终处理     **************/
#include <iostream>
using namespace std;

class Test
{
public:
    Test()
    {
        cout << "Test()" << endl;
    }
    ~Test()
    {
        cout << "~Test()" << endl;
    }
};

int main()
{
    static Test t;
    throw 1;
    
    return 0;
}

2、异常的最终处理

    2.1、如果main中异常无法被处理,terminate()结束函数会被自动调用
    2.2、默认情况下,terminate()调用abort()库函数来终止程序
    2.3、 abort()函数使得程序执行异常而立即退出。而不会像exit会先进行一些清理工作(如调用全局对象或静态局部对象的析构函数),再退出进程。
    2.4、 C++支持替换默认的terminate()函数实现。

3、自定义结束函数 (terminate)

    3.1、 自定义一个无返回值无参数的函数
        3.1.1、 不能抛出任何异常
        3.1.2、 函数中必须以某种方式结束当前程序(如exit或abort
    3.2、 调用set_terminate()设置自定义的结束函数
        3.2.1、 参数类型为void(*)()
        3.2.2、 返回值为默认的terminate()函数的入口地址

                   /**********    自定义结束函数   ************/
#include <iostream>
#include <cstdlib>
using namespace std;

//自定义结束函数
void my_terminate()
{
    cout << "void my_terminate()" << endl;
    //abort();//并不会清理全局变量
    exit(1);//调用exit会进行一些清理工作(如调用全局对象或静态局部对象的析构函数来进行清理),,只会清理一些全局变量
}

class Test
{
public:
    Test()
    {
        cout << "Test() " << endl;
    }
    ~Test()
    {
        cout << "~Test()" << endl;
    }
};

int main()
{
    set_terminate(my_terminate); //抛出异常没处理的话,系统自动调用这个函数,参数是无参函数指针,这是自定义的结束函数
    
    static Test t;//如果是局部变量,异常发生时析构函数不会被调用,因为,当异常发生后,会先执行my_terminate()结束,而该函数内调用的exit函数会清理全局变量。静态局部变量。
    
    throw 1;
    
    return 0;
}


4、析构函数中抛异常会发生什么(面试题)

    4.1、 可能造成terminate函数被重复调用
    4.2、 由terminate的重复调用,可能造成资源重复释放,从而造成系统的不稳定。
    4.3、 导致资源得不到正确的释放 。

/********       析构函数中抛异常     ********/
#include <iostream>
#include <cstdlib>
#include <exception>
using namespace std;


void my_terminate()
{
    cout << "void my_terminate()" << endl;
    
    exit(1);  //会进行一些全局函数的清理工作。。exit函数会清理全局变量。静态局部变量。
    //abort();  //abort直接退出程序,而不会进行清理的操作。不用担心重复释放带来的问题。
}

class Test
{
public:
    Test()
    {
        cout << "Test()" << endl;
    }
    ~Test()
    {
        cout << "~Test()" << endl;
        throw 2;
    }
           //在析构函数中抛出异常。
};

int main()
{
    set_terminate(my_terminate);    //设置自定义的结束函数
    
    static Test t;  //静态局部变量
    
    throw 1;//1。 由于main函数没有处理这个异常,会被传递到my_terminate中处理,这里是第一次调用my_terminate函数。
            //2。又因为my_terminate中调用了exit函数,会去清理全局变量,如调用t的构造函数来清理。但是构造函数中也抛出了一个异常,这将导致my_terminate函数重复被调用,造成资源的重复释放,从而造成系统的不稳定,(linux中做了处理,别的系统中就不一定做处理了。)                   

    return 0;
}

5、小结

    5.1、 如果异常没有被处理,最后terminate()结束整个程序
    5.2、 terminate()是整个程序释放系统资源的最后机会
    5.3、 结束函数可以自定义(可以set),但不能继续抛出异常
    5.4、 析构函数中不能抛出异常,可能导致terminate()多次调用






























































评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值