c++ primer plus 第15章友,异常和其他:异常,15.3.7 其他异常特性

c++ primer plus 第15章友,异常和其他:异常,15.3.7 其他异常特性

c++ primer plus 第15章友,异常和其他:异常,15.3.7 其他异常特性

文章目录

  • [c++ primer plus 第15章友,异常和其他:异常,15.3.7 其他异常特性](#c++ primer plus 第15章友,异常和其他:异常,15.3.7 其他异常特性)

15.3.7 其他异常特性

虽然 throw-catch 机制类似于函数参数和函数返回机制,但还是有些不同之处。其中之一是函数 fun()中的返回语句将控制权返回到调用 fun()的函数,但throw 语句将控制权向上返回到第一个这样的函数:包含能够捕获相应异常的try-catch 组合。例如,在程序清单15.12中,当函数hmeans()引发异常时,控制权

将传递给函数 means();然而,当 gmean()引发异常时,控制权将向上传递到 main()。另一个不同之处是,引发异常时编译器总是创建一个临时拷贝,即使异常规范和catch块中指定的是引用。例如,请看下面的代码:

cpp 复制代码
class problem(...);
void super()throw(problem)
{
	...
	if (oh_no)
	problem oops;//construct object
	throw oops;// throw it
	...
	}
try{
super();
catch(problem&p)
//statements
}

p将指向 oops的副本而不是 oops本身。这是件好事,因为函数 super()执行完毕后,oops 将不复存在。顺便说一句,将引发异常和创建对象组合在一起将更简单:

cpp 复制代码
throw problem();//construct and throw default problem object

您可能会问,既然 throw 语句将生成副本,为何代码中使用引用呢?毕竟,将引用作为返回值的通常原因是避免创建副本以提高效率。答案是,引用还有另一个重要特征:基类引用可以执行派生类对象。假设有一组通过继承关联起来的异常类型,则在异常规范中只需列出一个基类引用,它将与任何派生类对象匹配。假设有一个异常类层次结构,并要分别处理不同的异常类型,则使用基类引用将能够捕获任何异常对象;而使用派生类对象只能捕获它所属类及从这个类派生而来的类的对象。引发的异常对象将被第一个与之匹配的 catch 块捕获。这意味着catch 块的排列顺序应该与派生顺序相反:

cpp 复制代码
class bad 1{...};
class bad 2:public bad 1(...};
class bad 3:public bad 2{...};
...
void duper()
{
i f(oh_no)
 throw bad 1();
if (rats)
 throw bad 2();
if (drat)
 throw bad 3();
}
try{
duper();
catch(bad 3 &be)// statements
catch(bad 2 &be)(//statements
catch(bad 1 &be)// statements
}

如果将 bad 1&处理程序放在最前面,它将捕获异常bad_1、bad2和 bad 3;通过按相反的顺序排列,bad3异常将被bad3&处理程序所捕获,

提示:如果有一个异常类继承层次结构,应这样排列 catch 块:将捕获位于层次结构最下面的异常类的 catch语句放在最前面,将捕获基类异常的catch 语句放在最后面。

通过正确地排列 catch块的顺序,让您能够在如何处理异常方面有选择的余地。然而,有时候可能不知道会发生哪些异常。例如,假设您编写了一个调用另一个函数的函数,而您并不知道被调用的函数可能引发哪些异常。在这种情况下,仍能够捕获异常,即使不知道异常的类型。方法是使用省略号来表示异常类型,从而捕获任何异常:

cpp 复制代码
catch(...){//statements)// catches any type exception

如果知道一些可能会引发的异常,可以将上述捕获所有异常的catch块放在最后面,这有点类似于switch 语句中的 default:

cpp 复制代码
try{
duper();
}
catch(bad 3 &be)//statements
catch(bad 2 &be)//statements
catch(bad 1 &be)// statements
catch(bad hmean &h)
//statement
scatch(..)//statements
//catch whatever is left

可以创建捕获对象而不是引用的处理程序。在catch语句中使用基类对象时,将捕获所有的派生类对象,但派生特性将被剥去,因此将使用虚方法的基类版本。

相关推荐
A懿轩A42 分钟前
C/C++ 数据结构与算法【数组】 数组详细解析【日常学习,考研必备】带图+详细代码
c语言·数据结构·c++·学习·考研·算法·数组
机器视觉知识推荐、就业指导1 小时前
C++设计模式:享元模式 (附文字处理系统中的字符对象案例)
c++
半盏茶香1 小时前
在21世纪的我用C语言探寻世界本质 ——编译和链接(编译环境和运行环境)
c语言·开发语言·c++·算法
Evand J2 小时前
LOS/NLOS环境建模与三维TOA定位,MATLAB仿真程序,可自定义锚点数量和轨迹点长度
开发语言·matlab
LucianaiB2 小时前
探索CSDN博客数据:使用Python爬虫技术
开发语言·爬虫·python
Ronin3052 小时前
11.vector的介绍及模拟实现
开发语言·c++
✿ ༺ ོIT技术༻2 小时前
C++11:新特性&右值引用&移动语义
linux·数据结构·c++
字节高级特工2 小时前
【C++】深入剖析默认成员函数3:拷贝构造函数
c语言·c++
计算机学长大白3 小时前
C中设计不允许继承的类的实现方法是什么?
c语言·开发语言
suweijie7683 小时前
SpringCloudAlibaba | Sentinel从基础到进阶
java·大数据·sentinel