C++中的捕获异常机制catch参数中实参的类型不同,采取的处理方式则不相同,且与普通的函数调用还不一样,具体表现为当抛出异常throw A()或throw obj时,对象会进行一次额外的对象复制操作。

测试类实现如下:

  1. #include <iostream>
  2.  
  3. /**
  4. * 测试异常抛出与虚函数
  5. */
  6. using namespace std;
  7.  
  8. class A {
  9. public:
  10. A() {cout << "A() " << endl;}
  11. ~A(){cout << "~A()" << endl;}
  12. A(const A& a){cout << "A(a)" << endl;}
  13. virtual void func(){cout << "A::func()" << endl;}
  14. };
  15.  
  16. class B:public A {
  17. B() {cout << "B()" << endl;}
  18. B(const B &b) {cout << "B(b)" << endl;}
  19. ~B(){cout << "~B()" << endl;}
  20. virtual void func() {cout << "B::func()" << endl;}
  21. };

1)    当采用对象传递方式捕获异常时,在对象中会发生两次复制操作,一次为对象a复制给临时对象,二次为临时对象通过引用方式传递给实参b。

  1. void f1(const A &a)
  2. {
  3. try {
  4. cout << "------ function f1: --------" << endl;
  5. throw a;
  6. } catch( A b) {
  7. cout << "exception A b" << endl;
  8. }
  9. cout << "---- function f1 -------" << endl;
  10. }

该段代码执行结果如下:

------ function f1: --------

A(a)

A(a)

exception A b

~A()

~A()

---- function f1 -------

2)    当采用引用方式捕获异常时,就会少了上面第二次的复制开销,即生成临时对象直接作为参数传递。

  1. void f2(const A &a)
  2. {
  3. try {
  4. cout << "------ function f2: --------" << endl;
  5. throw a;
  6. } catch( const A &b) {
  7. cout << "exception A &b" << endl;
  8. }
  9. cout << "---- function f2 -------" << endl;
  10. }

执行结果如下:

  1. ------ function f2: --------
  2. A(a)
  3. exception A &b
  4. ~A()
  5. ---- function f2 -------

3)    如果直接抛出引用对象,系统会报错,因为异常处理机制不局限于当前函数,有可能在该函数之外。

  1. void f3(const A &a)
  2. {
  3. try {
  4. cout << "------ function f3: --------" << endl;
  5. throw &a;//引用异常,系统会意外终止
  6. } catch(const A &b) {
  7. cout << "exception A &b" << endl;
  8. }
  9. cout << "---- function f3 -------" << endl;
  10. }

4) 抛出异常时,可直接抛出对象,也可生成一个对象,不同的是这样会显式调用构造函数非复制构造函数。

  1. void f4(const A &a)
  2. {
  3. try {
  4. cout << "------ function f4: --------" << endl;
  5. throw A();
  6. } catch(const A &b) {
  7. cout << "exception A &b" << endl;
  8. }
  9. cout << "---- function f4 -------" << endl;
  10. }

执行结果如下:

  1. ------ function f4: --------
  2. A()
  3. exception A &b
  4. ~A()
  5. ---- function f4 -------

5)  在处理带有继承的异常类时,异常处理规则不是按照虚函数继承中”最优匹配(best fit)”原则,而是”最先匹配(first fit)”原则进行处理。

  1. void f5(const B& b)
  2. {
  3. try {
  4. cout << "------ function f5: --------" << endl;
  5. throw b;
  6. } catch(const A &a) {
  7. cout << "exception A &a" << endl;
  8. } catch(const B &b1) {
  9. cout << "exception B &b1" << endl;
  10. }
  11.  
  12. cout << "---- function f5 -------" << endl;
  13. }

该异常会匹配A而非B:

  1. ------ function f5: --------
  2. A()
  3. B(b)
  4. exception A &a
  5. ~B()
  6. ~A()
  7. ---- function f5 -------

C++中的异常处理机制的更多相关文章

  1. .NET中的异常处理机制(一)

    1.异常处理的总体指导思想 学习C#中的异常处理机制,大概要了解以下几点: 首先,我们需要知道的事所有具体异常都是继承自System.Exception基类的. 其次,要熟悉FCL类库内置好的一些异常 ...

  2. 【C++】异常简述(一):C语言中的异常处理机制

    人的一生会遇到很多大起大落,尤其是程序员. 程序员写好的程序,论其消亡形式无非三种:无疾而终.自杀.他杀. 当然作为一名程序员,最乐意看到自己写的程序能够无疾而终,因此尽快的学习异常处理机制是非常重要 ...

  3. 16、java中的异常处理机制

    异常:就是程序在运行时出现不正常情况.异常由来:问题也是现实生活中一个具体的事物,也可以通过java的类的形式进行描述.并封装成对象. 其实就是java对不正常情况进行描述后的对象体现. 对于问题的划 ...

  4. java中的异常处理机制

    java异常处理机制 1)在java语言中,通常将可能出现异常的语句放入try{}语句中,将出现错误后需要执行的语句放入到catch{}语句中,将无论是否发生异常都要执行的语句放在finally{}语 ...

  5. 深入理解C++中的异常处理机制

    异常处理 增强错误恢复能力是提高代码健壮性的最有力的途径之一,C语言中采用的错误处理方法被认为是紧耦合的,函数的使用者必须在非常靠近函数调用的地方编 写错误处理代码,这样会使得其变得笨拙和难以使用.C ...

  6. Java 中的异常处理机制

    生活中的异常:  不能够完整而顺利的完成一些工作 根据不同的异常进行相应的处理,而不会就此终端我们的生活 引出:  异常处理: 方式:  1.选择结构(逻辑判断)避免 demo:if逻辑处理异常 im ...

  7. C语言中的异常处理机制

    #define try if(!setjmp(Jump_Buffer)) 返回try现场后重新执行判断,所以有两次执行. http://blog.csdn.net/tian_dao_chou_qin/ ...

  8. Java中的异常处理机制《》

    异常机制已经成为判断一门编程语言是否成熟的标准,异常机制可以使程序中异常处理代码和正常业务代码分离,保证程序代码更加优雅,并提高程序健壮性. Java异常机制主要依赖于try.catch.finall ...

  9. Java中的异常处理机制的简单原理和应用?

    程序运行过程中可能出现各种"非预期"情况,这些非预期情况可能导致程序非正常结束. 为了提高程序的健壮性,Java提供了异常处理机制: try { s1... s2... s3... ...

随机推荐

  1. 让ie6对png透明图片支持起来

    [声明:此文仅是对低版本ie使用透明图片的一个研究,当时出于工作要求,所以花费了一番心思在兼容旧版本ie上,现在对ie8都是做降级处理了.不培养用户坏习惯.引导用户跟随潮流体验新技术应是我们前端开发者 ...

  2. AutoHotkey(AHK)

    这是2009年用过的一个软件,自动键盘执行的一个东西,能提高效率,代替人工击键和鼠标操作,现在中文化很好了,如下地址是中文文档 http://ahkcn.sourceforge.net/docs/Tu ...

  3. ADO.NET学习

    ADO.NET重要的类 在.NET访问MySql数据库时的几点经验! string connstr=Setting.Instance().GetConnectionString("MySql ...

  4. Struts2 Action下面的Method调用方法

    1. 在struts.xml中加入<constant name="struts.enable.DynamicMethodInvocation" value="tru ...

  5. HTML元素隐藏和显示

    在web前端开发过程中,经常会用到隐藏和显示元素的方法 总结:1.通过JS或Jquery控制          2.通过CSS样式控制 一.Js或jquery (jquery为例) 1.隐藏元素 使用 ...

  6. 【译】Permissions Best Practices Android M权限最佳做法

    Permissions Best Practices PreviousNext In this document Consider Using an Intent Don't Overwhelm th ...

  7. Spring MVC 3.0 深入及对注解的详细讲解

    核心原理 1.       用户发送请求给服务器.url:user.do 2.       服务器收到请求.发现Dispatchservlet可以处理.于是调用DispatchServlet. 3.  ...

  8. apache 重定向

    <IfModule mod_rewrite.c> RewriteEngine on RewriteCond %{HTTPS} !=on RewriteRule ^(.*) https:// ...

  9. java中创建字符串的两种方式(“”与new String())及区别

    结论:通过""创建的字符串实际上在java堆中只有一个,而通过new string创建出来的字符串在java堆中占有不同的内存. 第一个True表明这两个在内存中拥有相同的地址,那 ...

  10. CSS之照片集效果

    代码: <!DOCTYPE html><html><head> <title>照片影集</title> <meta charset=& ...