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

    • 自定义一个无返回值无参数的函数
      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() 多次调用
  • 相关阅读:
    Mvc model验证总结
    ArchSummit全球架构师峰会2017年深圳站 漫谈
    hiredis aeStop仅在redis命令的回调函数中生效 分析
    MirrorNetwork 基于jmdns和netty的android网络通信开源库
    pigeon物联网平台- developer portal web服务设计及实现
    物联网 command 原型设计及框架
    alljoyn:基于java动态代理的RPC实现原理分析
    IOT command (based on sip)client API设计 for java
    gateway & data management
    openhab入门介绍
  • 原文地址:https://www.cnblogs.com/PyLearn/p/10103115.html
Copyright © 2020-2023  润新知