1、方法参数的声明语法和catch语句的语法是一样的,你可能会认为主调方法调用一个方法,并向其传递参数,与抛出一个异常传递到catch语句是一样的,是的,有相同之处,但也有更大的不同。

2、主调方法调用一个方法,控制权转移,被调方法执行完,控制权最终还会返回到主调方法。但是,抛出异常到达catch语句,控制权不会再回到抛出端。

3、那么问题来了,抛出异常到达catch语句,控制权不再会到抛出端,这意味着,抛出的异常离开了作用域,自动销毁,那么catch语句还怎么捕获异常对象呢?

  解决办法是:建立一个临时对象,对抛出的异常进行copy构造。特别注意的是,不管什么情况,这个临时对象是必不可少的。根本原因就是,抛出端的异常对象销毁了,必须建立一个临时对象,才能传递到catch语句。而对于调用方法,如果是传递引用,不需要复制对象,因为主调方法中的局部对象并没有销毁。

4、即使抛出的异常没有销毁,抛出的异常对象到catch语句,中间也有一个临时对象。

5、这意味着,catch语句没有办法修改抛出端的异常对象,修改的只是副本,也就是临时对象。

6、从抛出异常到catch语句,之间建立一个临时对象,这个临时对象的类型,是抛出异常对象的表面类型。这就意味着,如果抛出的异常对象,表面类型与真实类型不一致,会造成对象切割。

7、这就导致下面的问题:抛出一个子类,在catch(Base& b)的语句中匹配成功,此时,b的表面类型和真实类型不一致,如果从新抛出b,建立的临时对象就是父类对象,也就是对象切割。也就是说,重新抛出的异常更加抽象,这显然不合理,那怎么办呢?直接使用throw,重新抛出当前的异常对象。并且不再产生一个新的临时对象。

8、catch语句中可以是传值,传引用,传const引用。对于传值,从临时对象到catch语句中形参,还要进行一次copy构造。因此,应该使用传引用,避免这一次的copy构造。那么,对于传const引用呢?

9、我们知道对于内置类型的临时对象,是不能修改的,但是,对于exception是个例外。思考一下,为什么对于内置类型的临时对象不能修改?

  临时对象的来源:隐式类型转化,方法返回值,抛出异常。

  对于隐式类型转化,临时对象不可修改。如果可修改,赋值给non-const引用,程序员修改这个引用,企图修改原数据,但实际上,修改的是临时对象,这与程序员的期望不符合,造成错觉。因此,禁止这种行为。

  对于方法返回值,产生的临时对象不可修改。这是为了,禁止客户对方法返回值进行赋值。

  但是,对于抛出异常产生的临时对象,可以修改。为什么?因为有这种需求:对抛出的异常追加一些额外信息。

10、现在考虑指针,抛出一个异常对象,catch语句的参数是指针,不能匹配成功,因为类型不吻合。不能把一个对象赋值给指针,必须取地址,赋值给指针。

11、继续思考,抛出一个指针,catch指针,相当于传递指针。这种情况,要保证指针指向的对象没有销毁。

12、调用方法,参数可以进行隐式类型转换。比如int转化为double。但是,对于抛出异常,不能进行这类的隐式转换。抛出异常可以进行的转换只有两种:子类转化为父类;有型指针转换为无型指针。

13、调用方法是最优匹配,而捕获异常是最先匹配。这就意味着,catch语句捕获的异常应该是,由具体到抽象,否则造成死代码。

【M12】了解“抛出一个exception”与“传递一个参数”或“调用一个虚函数”之间的差异的更多相关文章

  1. dubbo rpc调用抛出的Exception处理

    关于dubbo的Exception堆栈被吃处理,网上已经有比较多的解决方法,在我们的应用场景中,不希望RPC调用对方抛出业务exception,而是通过Resp中的errorCode,errorMsg ...

  2. 参数在一个线程中各个函数之间互相传递的问题(ThreadLocal)

    ThreadLocal最常用的地方就是为每个线程绑定一个数据库连接,HTTP请求,用户身份信息等,这样一个线程的所有调用到的处理函数都可以非常方便地访问这些资源. 一个ThreadLocal变量虽然是 ...

  3. VS2013 抛出 stackoverflow exception 的追踪

    本公司使用VWG.Caslte ActiveRecord.CSLA.net .Quantz.net 等组件做为公司的开发基础,自2007年以来,一直工作正常,但最近(2015.12月)以来,打开MDA ...

  4. 从constructor中抛出exception后,constructor会返回null吗?

    刚才琢磨这个问题主要是在想,如果constructor抛出了exception,那么返回的object是什么一个情况呢?如果我这个object中有一些关键的资源没有初始化,比如说Database co ...

  5. (转)spring异常抛出触发事务回滚策略

    背景:在面试时候问到事务方法在调用过程中出现异常,是否会传递的问题,平时接触的比较少,有些懵逼. spring异常抛出触发事务回滚策略 Spring.EJB的声明式事务默认情况下都是在抛出unchec ...

  6. Effective Java 第三版——74. 文档化每个方法抛出的所有异常

    Tips 书中的源代码地址:https://github.com/jbloch/effective-java-3e-source-code 注意,书中的有些代码里方法是基于Java 9 API中的,所 ...

  7. WCF服务创建与抛出强类型SOAP Fault

    原创地址:http://www.cnblogs.com/jfzhu/p/4060666.html 转载请注明出处 前面的文章<WCF服务的异常消息>中介绍过,如果WCF Service发生 ...

  8. Spring异常抛出触发事务回滚

    Spring.EJB的声明式事务默认情况下都是在抛出unchecked exception后才会触发事务的回滚 /** * 如果在spring事务配置中不为切入点(如这里的切入点可以定义成test*) ...

  9. java 检查抛出的异常是否是要捕获的检查性异常或运行时异常或错误

    /** * Return whether the given throwable is a checked exception: * that is, neither a RuntimeExcepti ...

随机推荐

  1. Android开发之动画(转)

    activity跳转的过渡效果,很漂亮,很全 注意,切换方法overridePendingTransition只能在startActivity和finish方法之后调用. 第一个参数为第一个Activ ...

  2. write_chip,read_chip

    int write_chip(UINT32 addr, UINT32 data) { if(0 == fpgaRWMode) /* localbus mode */ { UINT16 datah, d ...

  3. 大四实习准备4_java内部类

    2015-4-30 [昨天又可耻地休息了一天,懒劲比较大啊.跟懒劲有直接关系,这几天对幸福的感知也黯淡了,对未来的幸福不是那么渴望了.表现在对亲情和爱情上. 我想生活的本意是积极进取.茁壮生长并时常感 ...

  4. c# 产生随机字符串,包括大小写字母和数字

    #region MyRegion //產生密碼 protected static string GetPwd() { return CreateRandomNum123(2) + CreateRand ...

  5. s​e​t​ ​x​a​c​t​_​a​b​o​r​t ​用​法

    默认行为 默认为SET XACT_ABORT OFF,没有事务行为. SET XACT_ABORT ON SET XACT_ABORT ON分为两种: 1.总体作为一个事务,整体提交或整体回滚,格式为 ...

  6. LeetCode Implement Trie (Prefix Tree) (实现trie树3个函数:插入,查找,前缀)

    题意:实现trie树的3个功能,只含小写字母的串. 思路:老实做即可! class TrieNode { public: TrieNode* chd[]; bool flag; // Initiali ...

  7. HTML DOM 教程Part1

    2015-05-08 摘自W3C School HTML DOM HTML DOM 定义了访问和操作HTML文档的标准方法.HTML DOM 把 HTML 文档呈现为带有元素.属性和文本的树结构(节点 ...

  8. 《深入Java虚拟机学习笔记》- 第14章 浮点运算

    <深入Java虚拟机学习笔记>- 第13章 浮点运算

  9. Initializing nested object properties z

    public class Employee { public Employee() { this.Insurance = new Insurance(); } // Perhaps another c ...

  10. 《Python基础教程(第二版)》学习笔记 -> 第四章 字典

    字典是Python中唯一内建的映射类型. 字典中的值并没有特殊的顺序,但是都存储在一个特定的键(Key)里.键可以是数字.字符串甚至是元组. 字典的使用 某些情况下,字典比列表更加适用: 表征游戏棋盘 ...