异常规范

异常规范的理念看似有前途,但实际的使用效果并不好。

忽视异常规范之前,您至少应该知道它是什么样的,如下所示:

double harm(double a) throw(bad_thing);  //may throw bad_thing exception

double harm(double a) throw();    //doesn't throw an exception

其中throw()部分就是异常规范,它可能出现在函数原型和函数定义中,可包含类型列表,也可不包含。

异常规范的另一个作用是,让编译器添加执行运行阶段检查的代码,检查是否违反了异常规范。

这很难检查;

marm()可能不会引发异常,但它可能调用一个函数,而这个函数调用的另一个函数引发了异常。

另外,您给函数编写代码时它不会引发异常,但库更新后它却会引发异常。

总之,编程社区达成的意见是不要使用这个功能。

栈解退

假设try块没有直接调用引发异常的函数B,而是调用了对引发异常的函数B进行调用的函数A,即A调用了B。

则程序流程将从引发异常的函数B跳到包含try块和处理程序的函数。这涉及到栈解退。

首先要了解C++是如何处理函数调用和返回的。C++通常通过将信息放到中来处理函数调用

具体来说,程序将调用函数的指令地址(返回地址)放到栈中。

当被调用的函数执行完毕后,程序将使用该地址来决定从哪里开始继续执行。

另外函数调用将函数A参数放到栈中。在栈中这些函数参数被视为自动变量。

如果被调用函数B创建了新的自动变量,则这些变量也将被添加到栈中。

如果被调用函数B调用了另一个函数C,则函数C的信息也将被添加到栈中。以此类推;

当函数C结束时,程序流程将跳到该函数C被调用时存储的地址(返回地址)处,同时栈顶的元素被释放。

因此函数都通常返回到调用它的函数处,同时每个函数都在结束时释放器自动变量。

如果自动变量是类对象,则类的析构函数(如果有的话)也将被调用。

现在假设函数由于出现异常(而不是由于return)而终止,则程序也将释放栈中的内存。

但不会在释放栈的第一个返回地址后停止,而是继续释放栈,直到找到一个位于try块中的返回地址。

随后控制权将转移到位于try块尾的异常处理程序,而不是函数调用后面的第一条语句。

这个过程就被称为栈解退

和函数返回一样,对于栈中的自动类对象,类的析构函数将被调用。

然而函数返回仅仅处理该函数放在栈中的对象。

而throw语句则处理try块和throw之间整个函数调用序列放在栈中的对象。

接下来上代码,看看栈解退的例子:

 //error5.cpp  -- unwinding the stack
#include <iostream>
#include <cmath>
#include <string>
#include "exc_mean.h" class demo
{
private:
std::string word; public:
demo(const std::string & str)
{
word = str;
str::cout<<"demo "<<word<<" created\n";
} ~demo()
{
std::cout<<" demo "<<word<<" destroyed\n";
} void show() const
{
std::cout<<" demo "<<word<< " lives!\n";
}
}; //function prototypes
double hmean(double a, double b);
double gmean(double a, double b);
double means(double a, double b); int main()
{
using std::cout;
using std::cin;
using std::end; double x,y,z;
{
demo d1("found in block in main()");
cout<<"Enter two numbers:";
while(cin>>x>>y)
{
try{
z =means(x,y);
cout<<"The mean mean of"<<x<<" and "<<y
<<" is "<<z<<endl;
cout<<"Enter next pair:";
}
catch(bad_hmean & bg)
{
bg.mesg();
cout<<"Try again.\n";
continue;
}
catch(bad_gmean & hg)
{
cout<<hg.mesg();
cout<<"Values used:"<<hg.v1<<" , "
<<hg.v2<<endl;
cout<<"Sorry,you don't get to play any more.\n";
break;
}
}
d1.show();
}
cout<<"Bye!\n";
cin.get();
cin.get();
return ;
} double hmean(double a, double b)
{
if(a == -b)
throw bad_hmean(a,b);
return 2.0*a*b/(a+b);
} double gmean(double a, double b)
{
if(a<||b<)
throw bad_gmean(a,b);
return std::sqrt(a*b);
} double means(double a, double b)
{
double am, hm, gm;
demo d2("found in means()");
am = (a+b)/2.0;
try
{
hm = hmean(a,b);
gm = gmean(a,b); }
catch (bad_hmean & bg)
{
bg.mesg();
std::cout<<"Caught in means()\n";
throw; //重新抛出异常
}
d2.show();
return (am+hm+gm)/3.0; }

输出结果

demo found in block in main() created

Enter two numbers: 6 12

demo found in means() created

demo found in means() lives!

demo found in means() destroyed

The mean mean of 6 and 12 is 8.49509

6 -6

demo found in means() created

hmean(6, -6):invalid arguments: a=-b

Caught in means()

demo found in means() destroyed             //d2被释放掉了,且来不及调用d2.show()

hmean(6, -6):invalid arguments: a=-b       //异常重新抛出到main函数try块后面的catch

Try again.                                                 //continue重新开始循环

6 -8

demo found in means() created              //d2被创建

demo found in means() destroyed           //d2被释放,有异常产生,但是means函数中没有办法处理该异常gmean

gmean() arguments should be >=0         //这个gmean异常被main函数的catch模块捕获并处理

Values used: 6, -8

Sorry, you don't get to play any more.      //直接break,结束

demo found in block in main() lives!         //d1还在,程序运行到catch后面的语句

demo found in block in main() destroyed   //离开了模块,d1被销毁

Bye!

C++_异常5-异常规范和栈解退的更多相关文章

  1. “全栈2019”Java异常第二十章:自定义异常详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java异 ...

  2. _00020 妳那伊抹微笑_谁的异常最诡异第一期之 SqlServer RSA premaster secret error

    博文作者:妳那伊抹微笑 博客地址:http://blog.csdn.net/u012185296 博文标题:_00020 妳那伊抹微笑_谁的异常最诡异第一期之 SqlServer RSA premas ...

  3. 两种异常(CPU异常、用户模拟异常)的收集

    Windows内核分析索引目录:https://www.cnblogs.com/onetrainee/p/11675224.html 两种异常(CPU异常.用户模拟异常)的收集  文章的核心:异常收集 ...

  4. Java异常处理-----非运行时异常(受检异常)

    非运行时异常(受检异常) 如果出现了非运行时异常必须进行处理throw或者try{}catch(){}处理,否则编译器报错. 1:IOException 使用要导入包import java.io.IO ...

  5. Python档案袋(异常与异常捕获 )

    无异常捕获 程序遇到异常会中断 print( xxx ) print("---- 完 -----") 得到结果为: 有异常捕获 程序遇到异常会进入异常处理,并继续执行下面程序 tr ...

  6. Java 异常的捕获与处理详解 (一)

    一,异常的产生(Exception) 异常是程序之中导致程序中断的一种指令流,异常一旦出现并且没有进行合理处理的话,那么程序就会中断执行. An exception is a flow of inst ...

  7. 重学c#系列——异常续[异常注意事项](七)

    前言 对上节异常的补充,也可以说是异常使用的注意事项. 正文 减少try catch的使用 前面提及到,如果一个方法没有实现该方法的效果,那么就应该抛出异常. 如果有约定那么可以按照约定,如果约定有歧 ...

  8. 异常概念&异常体系和异常分类

    异常概念 异常:指的是程序在执行过程中,出现的非正常的情况,最终会导致JVM的非正常停止. 在Java等面向对象的编程语言中,异常本身是一个类,产生异常就是创建异常对象并抛出了一个异常对象.Java处 ...

  9. SQL Server 表的管理_关于事务的处理的详解(案例代码)

    SQL Server 表的管理_关于事务的处理的详解(案例代码) 一.SQL 事务 1.1SQL 事务 ●事务是在数据库上按照一定的逻辑顺序执行的任务序列,既可以由用户手动执行,也可以由某种数据库程序 ...

随机推荐

  1. ubuntu 编译并安装resin3.1.12+nginx1.2.6

    一.先装jdk 先建立如下两个目录: mkdir /usr/lib/jvm mkdir /usr/lib/jvm/java 把jdk-6u26-linux-x64.bin文件传到上面目录下: chmo ...

  2. 06-Location详解之精准匹配

    之前nginx不是编译过吗?现在重新make install一下. 刚刚这个是我们新安装的.原始版的nginx,配置文件比较少,便于我们做调试. 试试精准匹配的概念. 匹配的是/.优先匹配这个最精准的 ...

  3. c++ 流状态

    这里是对cin中函数的作用的补充.

  4. 在ubuntu12.04上安装6款顶级漂亮的BURG主题

    BURG 基本上是一个基于GRUB的Linux引导装载程序.BURG格有一个高度可配置的菜单系统,可选择文本和图形模式.简而言之,BURG可广泛定制,有良好免费的BURG主题.选择自己最喜欢的,下面我 ...

  5. IDEA maven打包时跳过测试

    配置这个install -Dmaven.test.skip=true, 可以跳过business项目本地启动自动跑测试用例

  6. 118. Pascal's Triangle杨辉三角形(全部/一行)

    [抄题]: Given numRows, generate the first numRows of Pascal's triangle. For example, given numRows = 5 ...

  7. vs2017不是完全支持c99

    1.比如c99里面有一个特性, int count[]={0,[5]=7,9,10} 这种在VS2017里面是编译不通过的.; 2.c99有一个变长数组的概念(VLA),但是vs2017不支持.

  8. HttpRuntime.Cache

    a.在Web开发中,我们经常能够使用到缓存对象(Cache),在ASP.NET中提供了两种缓存对象,HttpContext.Current.Cache和HttpRuntime.Cache,那么他们有什 ...

  9. datetime 2017-10-21 10:09:02.560 转年月日的时间类型

    sql语句时间转年月日格式: 适用于多种时间格式 select  REPLACE(STUFF(CONVERT(char(10), REPLACE(CONVERT(varchar(10),'2017-1 ...

  10. Image Processing, Analysis & and Machine Vision - A MATLAB Companion

    Contents目录 Chapter 0: Introduction to the companion book本辅导书简介 Chapter 1: Introduction 简介 Viewing an ...