C++中函数异常规格的说明

作者:子宇24

链接:https://www.cnblogs.com/dishengAndziyu/p/10920150.html

1、本文介绍一个新的概念,它是一个重要的概念,并且是 C++ 中的一个高级主题;

 

2、问题:


  • 如何判断一个函数(不是自己写的,有可能是第三方库中的函数)是否会抛出异常,以及抛出那些异常?

    学习了异常处理,我们在调用一个函数的时候,就应该知道这个函数会不会抛出异常,如果会,抛那些:

  • 如果是第三方库的函数,只有函数声明,没有函数实现,则也不知道会不会抛出异常; 

  • 查看函数文档也是不错的方法,但是如果手头文档和真实的库的版本不匹配,有可能查到的东西就是不准确的;

   

3、异常规格说明:


  • C++ 提供语法用于声明函数所抛出的异常;

  • 异常声明作为函数声明的修饰符,写在参数列表后面:

    /* 可能抛出任何异常 */


          void func1();          /* 只能抛出的异常类型:char 和 int */          void func2() throw(char, int);          /* 不抛出任何异常 */          void func3() throw();


4、异常规格说明的意义:


  • 提示函数调用者必须做好异常处理的准备;

    如果想知道调用的函数会抛出哪些类型的异常时,只用打开头文件看看这个函数是怎么声明的就可以了;

  • 提示函数的维护者不要抛出其它异常;

  • 异常规格说明是函数接口的一部分;

    用于说明这个函数如何正确的使用;

   

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

 

6、下面的代码输出什么?


640?wx_fmt=png


7、异常规格之外的异常编程实验:


#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;}


  • BCC 显示:

    func()

    Abnormal program termination

  • g++ 显示:

    terminate called after throwing an instance of \'char\'

    已放弃

  • VC 2010 显示:

    func()

    catch(char)

   

8、unexpected() 函数说明:


  • 函数抛出的异常不在规格说明中,全局 unexpected() 被调用;

  • 默认的 unexpected() 函数会调用全局的 terminate() 函数;

    这是 BCC 和 g++ 编译器的行为;

  • 可以自定义函数替换默认的 unexpected() 函数实现;

    VC 2010 编译器的也不遵循行为;

  • 注意:不是所有的 C++ 编译器都支持这个标准行为;

    在异常处理这个技术点上面,编译器实现是有差异的,如果我们未来的项目中确实的要用到函数的异常规格说明时,我们最好的写一个小的测试程序,看看当前项目里面所使用的 C++ 编译器在这一个技术点的行为是怎样的,有没有遵循标准的 C++ 规范;

   

9、unexpected() 函数的替换:


  • 自定义一个无返回值无参数的函数:

    能够再次抛出异常:

    当异常符合触发函数的异常规格说明时,恢复程序执行;

    见 本文10 中程序 throw 1;

    否则,调用全局 terminate() 函数结束程序;

  • 调用 set_unexpected() 设置自定义的异常函数:

    参数类型为 void(*)();

    返回值为默认的 unexpected() 函数入口地址;

      

10、自定义 unexpected() 函数编程实验:


#include <iostream>#include <cstdlib>#include <exception>using namespace std;void my_unexpected(){    cout << "void my_unexpected()" << endl;    // exit(1);  // 退出;    throw 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;}


  • exit(1) 结果:

    g++ 编译器:

    func()

    void my_unexpected()

    BCC 编译器:

    func()

     void my_unexpected()

    VC 2010 编译器:

    func()

    catch(char)  // 未有遵循标准 C++ 规范;

  • throw 1 结果:

    g++ 编译器:

    func()

    void my_unexpected()

    catch(int)  //与触发函数 func() 的异常规格符合,于是程序恢复执行;

    BCC 编译器:

    func()

    void my_unexpected()

    catch(int)

    VC 2010 编译器:

    func()

    catch(char)  // 未有遵循标准 C++ 规范,直接捕获,然后处理;

  • 如果以后项目开发,会使用函数异常说明这个技术点,最好在项目开发前写一些小程序测试下当前使用的 C++ 编译器有没有很好的遵循 C++ 的规范;

   

11、小结:


  • C++ 中的函数可以声明异常规则说明;

  • 异常规格说明可以看作接口的一部分;

  • 函数抛出的异常不在规格说明中,unexpected() 被调用;

  • unexpected() 中能够再次抛出异常;

    异常能够匹配,恢复程序的执行;

    否则,调用 terminate() 结束程序;

    un_expected() 函数是正确处理异常的最后机会,如果没有抓住,terminate() 函数会被调用,当前程序以异常告终;

640?wx_fmt=jpeg


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值