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() 结束程序

C++解析-外传篇(2):函数的异常规格说明的更多相关文章

  1. C++解析-外传篇(3):动态内存申请的结果

    0.目录 1.动态内存申请一定成功吗? 2.new_handler() 函数 3.小结 1.动态内存申请一定成功吗? 问题: 动态内存申请一定成功吗? 常见的动态内存分配代码: C代码: C++代码: ...

  2. C++解析-外传篇(1):异常处理深度解析

    0.目录 1.异常的最终处理 2.结束函数terminate() 3.小结 1.异常的最终处理 问题: 如果在main函数中抛出异常会发生什么? 如果异常不处理,最后会传到哪里? 下面的代码的输出什么 ...

  3. jQuery2.x源码解析(回调篇)

    jQuery2.x源码解析(构建篇) jQuery2.x源码解析(设计篇) jQuery2.x源码解析(回调篇) jQuery2.x源码解析(缓存篇) 通过艾伦的博客,我们能看出,jQuery的pro ...

  4. DEX文件解析--7、类及其类数据解析(完结篇)

    一.前言    前置技能链接:       DEX文件解析---1.dex文件头解析       DEX文件解析---2.Dex文件checksum(校验和)解析       DEX文件解析--3.d ...

  5. jQuery2.x源码解析(缓存篇)

    jQuery2.x源码解析(构建篇) jQuery2.x源码解析(设计篇) jQuery2.x源码解析(回调篇) jQuery2.x源码解析(缓存篇) 缓存是jQuery中的又一核心设计,jQuery ...

  6. jQuery2.x源码解析(构建篇)

    jQuery2.x源码解析(构建篇) jQuery2.x源码解析(设计篇) jQuery2.x源码解析(回调篇) jQuery2.x源码解析(缓存篇) 笔者阅读了园友艾伦 Aaron的系列博客< ...

  7. jQuery2.x源码解析(设计篇)

    jQuery2.x源码解析(构建篇) jQuery2.x源码解析(设计篇) jQuery2.x源码解析(回调篇) jQuery2.x源码解析(缓存篇) 这一篇笔者主要以设计的角度探索jQuery的源代 ...

  8. PE文件解析 基础篇

    PE文件解析 基础篇 来源 https://bbs.pediy.com/thread-247114.htm 前言 之前学习了PE格式,为了更好的理解,决定写一个类似LoadPE的小工具. 编译器是VS ...

  9. 自定义UDF函数应用异常

    自定义UDF函数应用异常 版权声明:本文为yunshuxueyuan原创文章.如需转载请标明出处: http://www.cnblogs.com/sxt-zkys/QQ技术交流群:299142667 ...

随机推荐

  1. WPF binding Tag

    使用一个控件控制另外一个控件的显示与隐藏.

  2. [.NET] 使用HttpClient操作HFS (HTTP File Server)

    前言 本篇文章介绍如何使用HttpClient操作HFS (HTTP File Server),为自己留个纪录也希望能帮助到有需要的开发人员.关于HTTP File Server的介绍.安装.设定,可 ...

  3. QSS 样式示例:QTreeWidget, QComboBox,QSlider,QSpinBox

    目录 Image 填充整个控件的区域 QTreeWidget QSpinbox 的上翻下翻按钮和箭头 QComboBox 的设置,大坑 QSlider 最近需要对一个软件加上Qt界面和 的样式,第一次 ...

  4. Pearson Distance

    Pearson Distance: where: 1.  is the covariance 2.  is the standard deviation of 3.  is the standard ...

  5. JPA error org.hibernate.AnnotationException: No identifier specified for entity

    错误:org.hibernate.AnnotationException: No identifier specified for entity 原因:JPA所使用的Entity需要标注@Id,在引用 ...

  6. Python Requests库入门——应用实例-京东商品页面爬取+模拟浏览器爬取信息

    京东商品页面爬取 选择了一款荣耀手机的页面(给华为打广告了,荣耀play真心不错) import requests url = "https://item.jd.com/7479912.ht ...

  7. 软件工程 speedsnail 第二次冲刺10

    20150527 完成任务:蜗牛碰到线后速度方向的调整:已经基本实现多方向的反射: 遇到问题: 问题1 反射角的问题 解决1 利用tan()三角函数 明日任务: 大总结.找到新问题.布置下一次冲刺方案

  8. Python 变量和常量及数据类型

    一.变量的命名 变量由字母.数字和下划线组成.变量的第1个字符必须是字母或下划线. 二.变量的赋值 例: x = 1 三.局部变量 局部变量只能在函数或者代码段内使用. 四.全局变量 在函数之外定义的 ...

  9. 使用JSon实现三级联动

    JSon实现三级联动 我觉得我这个方法比较麻烦,但是目前技术还比较弱,所以先做个笔记自己理解.目前没有和后台交互,只是在前台页面实现了 jQuery和JSon数据实现的,代码如下: <!DOCT ...

  10. struts2 jsp的session取值 if判断

    model有个类user,其中有个string属性direction(方向) 在LoginAction中 登入成功 就 ActionContext actionContext = ActionCont ...