zoukankan      html  css  js  c++  java
  • 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() 多次调用
  • 相关阅读:
    docker API 配置与使用
    docker 启动 nginx 访问不了的问题
    微信小程序
    JavaScript -- 继承与原型链
    Chrome Google 快捷键
    jquery中attr和prop的区别
    Vue购物车实例
    jquery添加html代码的几种方法
    DeepFaceLab错误:DLL Load failed 找不到指定模块!
    DeepFaceLab:手动提取高精度脸图,减少抖动!
  • 原文地址:https://www.cnblogs.com/PyLearn/p/10103115.html
Copyright © 2011-2022 走看看