专栏首页Linux知识积累C++中函数异常规格的说明

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、下面的代码输出什么?

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() 函数会被调用,当前程序以异常告终;

本文分享自微信公众号 - Linux知识积累(LinuxLearning365),作者:子宇24

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-07-03

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • linux下制作deb的方法总结

    deb是Unix系统(其实主要是Linux)下的安装包,基于 tar 包,因此本身会记录文件的权限(读/写/可执行)以及所有者/用户组。

    用户5807183
  • 创建 REST API 的最佳入门教程

    如果你看到这里,你以前可能听说过API 和REST,然后你就会想:“这些都是什么东西?”。也许你已经了解过一些这方面的知识,但却不知道从何入手。在这个教程中,我...

    用户5807183
  • Github使用方法(完整版)

    打开 GitHub 网站 https://github.com/, 注册账号并登录,进入个人主页。

    用户5807183
  • 【像训练CNN一样快速训练RNN】全新RNN实现,比优化后的LSTM快10倍

    【新智元导读】如何有效训练RNN是一个活跃的研究领域,有很多方法,但还没有哪种表现出了明显的优势,因此也让今天要介绍的这项工作值得注意。来自ASAPP公司和MI...

    新智元
  • 7.18 VR扫描:亚马逊Prime日大促销,Oculus Rift优惠50美元!

    以色列3D成像公司Mantis Vision完成5500万美元融资,三星、联美控股投资

    VRPinea
  • 财报公布,联想遭受口诛笔伐的原因何在?

    孟永辉
  • 【译】2019年开始使用Typescript

    基于2018年Stack Overflow Developer的调研,TypeScript作为编程语言比JavaScript更受“喜爱”。TypeScript在...

    嘉明
  • Android各大手机品牌手机跳转到权限管理界面

    最近项目中遇到这样个需求场景:<br > 当我们的用户使用App时不小心拒绝了某项必要权限,而导致无法正常使用。这时候希望重新去打开该权限,那么问题来了,And...

    用户2802329
  • DeepMind新论文:类脑语言模型——AI达到人类水平语言理解能力的路线图

    DeepMind、斯坦福大学、博世人工智能中心、Google Research以及 LMU Munich的研究团队最近发表论文《将机器语言模型扩展到人类水平的语...

    新智元
  • python使用stub模块调用wcf

    对官方例子的简单解释:http://ully.iteye.com/blog/1266320

    py3study

扫码关注云+社区

领取腾讯云代金券