• C++解析-外传篇(2):函数的异常规格说明


    0.目录

    1.异常规格说明

    2.unexpected() 函数

    3.小结

    1.异常规格说明

    问题:
    如何判断一个函数是否会抛出异常,以及抛出哪些异常?

    • C++提供语法用于声明函数所抛出的异常
    • 异常声明作为函数声明的修饰符,写在参数列表后面

    异常规格说明的意义:

    • 提示函数调用者必须做好异常处理的准备
    • 提示函数的维护者不要抛出其它异常
    • 异常规格说明是函数接口的一部分

    问题:
    如果抛出的异常不在声明列表中,会发生什么?

    下面的代码的输出什么?

    示例——异常规格之外的异常:

    #include <iostream>
    
    using namespace std;
    
    void func() throw(int)
    {
        cout << "func()";
        cout << endl;
        
        throw 'c';
    }
    
    int main()
    {
        try
        {
            func();
        }
        catch(int)
        {
            cout << "catch(int)";
            cout << endl;
        }
        catch(char)
        {
            cout << "catch(char)";
            cout << endl;
        }
        
        return 0;
    }
    

    运行结果为:

    [root@bogon Desktop]# g++ test.cpp
    [root@bogon Desktop]# ./a.out 
    func()
    terminate called after throwing an instance of 'char'
    Aborted (core dumped)
    

    (不同编译器运行结果不一样。)

    2.unexpected() 函数

    • 函数抛出的异常不在规格说明中,全局 unexpected() 被调用
    • 默认的 unexpected() 函数会调用全局的 terminate() 函数
    • 可以自定义函数替换默认的 unexpected() 函数实现
    • 注意:不是所有的C++编译器都支持这个标准行为

    unexpected() 函数的替换:

    • 自定义一个无返回值无参数的函数
      1. 能够再次抛出异常
        1. 当异常符合触发函数的异常规格说明时,恢复程序执行
        2. 否则,调用全局 terminate() 函数结束程序
    • 调用 set_unexpected () 设置自定义的异常函数
      1. 参数类型为 void (*) ()
      2. 返回值为默认的 unexpected() 函数入口地址

    示例1——自定义 unexpected() 函数:

    #include <iostream>
    #include <cstdlib>
    #include <exception>
    
    using namespace std;
    
    void my_unexpected()
    {
        cout << "void my_unexpected()" << endl;
        exit(1);
    }
    
    void func() throw(int)
    {
        cout << "func()";
        cout << endl;
        
        throw 'c';
    }
    
    int main()
    {
        set_unexpected(my_unexpected);
        
        try 
        {
            func();
        } 
        catch(int) 
        {
            cout << "catch(int)";
            cout << endl;
        } 
        catch(char) 
        {
            cout << "catch(char)";
            cout << endl;
        }
        
        return 0;
    }
    

    运行结果为:

    [root@bogon Desktop]# g++ test.cpp
    [root@bogon Desktop]# ./a.out 
    func()
    void my_unexpected()
    

    exit();改为throw 1;后的运行结果:
    示例2——自定义 unexpected() 函数:

    void my_unexpected()
    {
        cout << "void my_unexpected()" << endl;
        // exit(1);
        throw 1;
    }
    

    运行结果为:

    [root@bogon Desktop]# g++ test.cpp
    [root@bogon Desktop]# ./a.out 
    func()
    void my_unexpected()
    catch(int)
    

    (程序恢复执行了。)
    (unexpected() 函数是正确处理异常的最后机会,如果没有抓住这次机会,全局的 terminate() 函数就会被调用,当前程序就只能以异常结束告终。)

    3.小结

    • C++中的函数可以声明异常规格说明
    • 异常规格说明可以看作接口的一部分
    • 函数抛出的异常不在规格说明中,unexpected() 被调用
    • unexpected() 中能够再次抛出异常
      1. 异常能够匹配,恢复程序的执行
      2. 否则,调用 terminate() 结束程序
  • 相关阅读:
    iOS 开发学习之 User Interface(2)UIWindow 视窗
    iOS 开发学习之 User Interface(1)APP 生命周期
    OC-学习Tips
    初识Objective-C
    Android代码报错:setContentView(R.layout.activity_main)
    解决Discuz! info: MySQL Query Error
    技术网站
    java调用机器上的shell脚本
    素材网、图片库
    database工具
  • 原文地址:https://www.cnblogs.com/PyLearn/p/10103476.html
Copyright © 2020-2023  润新知