异常、类和继承以三种方式相互关联。

首先,可以像标准C++库所做的那样,从一个异常类派生出另一个。

其次,可以在类定义中嵌套异常类声明来组合异常。

第三,这种嵌套声明本身可以被继承,还可以作为基类。

接下来用一个例子进行相关的探索;

以下这个头文件声明了一个Sales类,它用于存储一个年份以及一个包含12个月销售数据的数组。

LabelledSales类是从Sales派生而来的。新增了一个用于存储数据标签的成员。

  1. //sales.h -- exception and inheritance
  2. #include <stdexcept>
  3. #include <string>
  4.  
  5. class Sales
  6. {
  7. public:
  8. enum {MONTHS = };
  9. class bad_index : public std::logic_error
  10. {
  11.  
  12. };
  13. explicit Sales(int yy = );
  14. Sales(int yy, const double * gr, int n);
  15. virtual ~Sales() {}
  16. int Year() const { return year;}
  17. virtual double operator[] (int i) const;
  18. virtual double & operator[] (int i);
  19.  
  20. private:
  21. double gross[MONTHS];
  22. int year;
  23. };
  24.  
  25. class LabeledSales : public Sales
  26. {
  27. public:
  28. class nbad_index : public Sales::bad_index
  29. {
  30. private:
  31. std::string lbl;
  32. public:
  33. nbad_index(const std::string & lb, int ix, const std::string & s = "Index error in LabeledSales object\n");
  34. const std::string & label_val() const {return lbl;}
  35. virtual ~nbad_index() throw() {}
  36. }
  37. explicit LabeledSales(const std::string & lb = "none", int yy = );
  38. LabeledSales(const std::string & lb, int yy, const double * gr, int n);
  39. virtual ~LabeledSales() {}
  40. const std::string & Label() const {return label;}
  41. virtual double operator[] (int i) const;
  42. virtual double & operator[] (int i);
  43.  
  44. private:
  45. std::string label;
  46.  
  47. };

分析以下头文件的细节;首先,符号常量位于Sales类的保护部分,这使得派生类能够使用这个值。

接下来,bad_index被嵌套在Sales类的公有部分中,这使得客户类的catch块可以使用这个类作为类型。

注意,在外部使用这个类型时,需要使用Sales::bad_index来标识。这个类是从logic_error类派生而来的,能够存储和报告数组索引的超界值。

nbad_index类被嵌套到LabeledSales的公有部分,这使得客户类可以通过LabeledSales::nbad_index来使用它。

它是从bad_inde类派生而来的,因此nbad_index归根结底也是从logic_error派生而来的。

这两个类都有重载的operator[]()方法,这些方法用于访问存储在对象中的数组元素,并在索引超界时引发异常。

接下来是源文件,是没有声明为内联的方法的实现。

  1. //sales.cpp --Sales implementation
  2. #include "sales.h"
  3. using std::string;
  4.  
  5. Sales::bad_index::bad_index(int ix, const string & s)
  6. : std::logic_error(s), bi(ix)
  7. {
  8.  
  9. }
  10.  
  11. Sales::Sales(int yy)
  12. {
  13. year = yy;
  14. for(int i = ; i < Months; ++i)
  15. gross[i] = ;
  16. }
  17.  
  18. Sales::Sales(int yy, const double * gr, int n)
  19. {
  20. year = yy;
  21. int lim = (n< MONTHS)? n : MONTHS;
  22. int i;
  23. for (i=;i<MONTHS;++i)
  24. gross[i] = gr[i];
  25. // for i >n and i <MONTHS
  26. for (;i < MONTHS;++i)
  27. gross[i] = ;
  28. }
  29.  
  30. double Sales::operator[](int i) const
  31. {
  32. if(i< || i>=MONTHS)
  33. throw bad_index(i);
  34. return gross[i];
  35. }
  36.  
  37. double & Sales:;operator[] (int i)
  38. {
  39. if(i< || i>=MONTHS)
  40. throw bad_index(i);
  41. return gross[i];
  42. }
  43.  
  44. LabeledSales::nbad_index::nbad_index(const string & lb, int ix, const string & s):Sales::bad_index(ix,s)
  45. {
  46. lbl =lb;
  47. }
  48.  
  49. LabeledSales::LabeledSales(const string & lb, int yy):Sales(yy)
  50. {
  51. label=lb;
  52. }
  53.  
  54. LabeledSales::LabeledSales(const string & lb, int yy, const double * gr, int n):Sales(yy, gr, n)
  55. {
  56. label = lb;
  57. }
  58.  
  59. double LabeledSales::operator[](int i) const
  60. {
  61. if(i< || i>=MONTHS)
  62. throw nbad_index(Label(), i);
  63. return Sales::operator[](i);
  64. }
  65.  
  66. double & LabeledSales::operator[](int i)
  67. {
  68. if(i< || i>=MONTHS)
  69. throw nbad_index(Label(), i);
  70. return Sales::operator[](i);
  71. }

接下来编写程序运行一下:

  1. //use_sale.cpp --nested exceptions
  2. #include <iostream>
  3. #include "sales.h"
  4.  
  5. int main()
  6. {
  7. using std::cout;
  8. using std::cin;
  9. using std::endl;
  10.  
  11. double vals1[] =
  12. {
  13. , , , , , ,
  14. , , , , ,
  15. };
  16.  
  17. double vals[] =
  18. {
  19. ,,,,,,
  20. ,,,,,
  21. };
  22.  
  23. Sales sales1 ();
  24. LabeledSales sales2();
  25.  
  26. cout<<"First try block:\n";
  27. try
  28. {
  29. int i;
  30. cout<<"Year = "<< sales1.Year() << endl;
  31. for (i =; i<; ++i)
  32. {
  33. cout<<sales1[i]<<' ';
  34. if (i % == )
  35. cout<<endl;
  36. }
  37. cout<<"Year = "<<sales2.Year()<<endl;
  38. cout<<"Label = "<<sales2.Label()<<endl;
  39. for (i = ; i<=; ++i)
  40. {
  41. cout<<sales2[i]<<' ';
  42. if (i % == )
  43. cout<<endl;
  44. }
  45. cout<<"End of try block 1.\n";
  46. }
  47. catch(LabeledSales::nbad_index & bad)
  48. {
  49. cout<<bad.what();
  50. cout<<"Company: "<<bad.label_val()<<endl;
  51. cout<<"bad index: "<<bad.bi_val()<<endl;
  52. }
  53. catch(Sales::bad_index & bad)
  54. {
  55. cout<<bad.what();
  56. cout<<"bad index: "<<bad.bi_val()<<endl;
  57. cout << "\nNext try block:\n";
  58. try
  59. {
  60. sales2[] =37.5;
  61. sales1[]=;
  62. cout<<"End of try block 2.\n";
  63. }
  64. catch(LabeledSales::nbad_index & bad)
  65. {
  66. cout << bad.what();
  67. cout << "Company:" <<bad.label_val()<<endl;
  68. cout << "bad index:" << bad.bi_val() << endl;
  69. }
  70. catch(Sales::bad_index & bad)
  71. {
  72. cout << bad.what();
  73. cout << "bad.bi_val()"<<endl;
  74. }
  75. cout << "done\n";
  76. return ;
  77. }

C++_异常8-异常、类和基础的更多相关文章

  1. 网易云课堂_C++程序设计入门(下)_第9单元:白公曾咏牡丹芳,一种鲜妍独“异常”_第9单元 - 作业5:OJ编程 - 使用异常进行图形类的错误处理

    第9单元 - 作业5:OJ编程 - 使用异常进行图形类的错误处理 查看帮助 返回   温馨提示: 1.本次作业属于Online Judge题目,提交后由系统即时判分. 2.学生可以在作业截止时间之前 ...

  2. Util应用程序框架公共操作类(五):异常公共操作类

    任何系统都需要处理错误,本文介绍的异常公共操作类,用于对业务上的错误进行简单支持. 对于刚刚接触.Net的新手,碰到错误的时候,一般喜欢通过返回bool值的方式指示是否执行成功. public boo ...

  3. python进阶八_警告和异常

    心情有点纠结,怎么说呢,倒不是由于其它学习上的事情,反而是由于生活上狗血的剧情逼着人偏离,渐行渐远,人跟人之间有误会也是正常的,可能是由于交流不够,彼此不够了解吧,希望能尽快度过这一段纠结的日子,简单 ...

  4. springmvc在处理请求过程中出现异常信息交由异常处理器进行处理,自定义异常处理器可以实现一个系统的异常处理逻辑。为了区别不同的异常通常根据异常类型自定义异常类,这里我们创建一个自定义系统异常,如果controller、service、dao抛出此类异常说明是系统预期处理的异常信息。

    springmvc在处理请求过程中出现异常信息交由异常处理器进行处理,自定义异常处理器可以实现一个系统的异常处理逻辑. 1.1 异常处理思路 系统中异常包括两类:预期异常和运行时异常RuntimeEx ...

  5. java异常和错误类总结(2016.5)

    看到以前2016.5.写的一点笔记,拿过来放在一起. java异常和错误类总结 最近由于考试和以前的面试经常会遇到java当中异常类的继承层次的问题,弄得非常头大,因为java的异常实在是有点多,很难 ...

  6. AJPFX关于异常和file类的总结

    /** * 各位坛友注意啦!对我这个帖子有任何的疑惑的,可以尽管留帖提问,我会在看到的第一时间回贴,既然写得出这帖子,* 就要对看这帖子的人负责,所以有问题,尽管问!* * * 这块没学好的同学,可以 ...

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

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

  8. java异常继承何类,运行时异常与一般异常的区别

    一.基本概念 Throwable是所有异常的根,java.lang.ThrowableError是错误,java.lang.ErrorException是异常,java.lang.Exception ...

  9. TypeScript完全解读(26课时)_7.ES6精讲 - 类Class基础

    ES6精讲 - 类Class基础 es5中创建构造函数和实例 原来在es5中的写法 定义好Point后,在原型对象上定义getPostion的方法 实例自身是没有这个方法的,我们调用的时候会去创建他的 ...

  10. java多线程系类:基础篇:09之interrupt()和线程终止方式

    概要 本章,会对线程的interrupt()中断和终止方式进行介绍.涉及到的内容包括:1. interrupt()说明2. 终止线程的方式2.1 终止处于"阻塞状态"的线程2.2 ...

随机推荐

  1. PHP json_encode 让URL//不转义

    $json_info=json_encode((object)$data,JSON_UNESCAPED_SLASHES);

  2. Solidity oraclize query apikey加密

    solidity 程序中如果用到oraclize query,api调用需要apikey,则最好加密apikey,否则公开solidity代码时会连同apikey一起公开. 加密方法: https:/ ...

  3. while 和do while循环的区别

    int a; scanf_s("%d",&a); while(a>0) { //do something; } while循环先要判断条件是否成立,如果不成立,那么就 ...

  4. Django rest_framework----序列化组件

    生成hypermedialink serializer.pclass BookModelSerializers(serializers.ModelSerializer): class Meta: mo ...

  5. 数据库MySQL 之 库操作

    数据库MySQL 之 库操作 浏览目录 系统数据库简介 数据库操作 命名规范 用户权限 修改密码 忘记密码 中文乱码问题 一.系统数据库简介 information_schema :虚拟库,不占用磁盘 ...

  6. Django-Web框架之创建项目和应用

    Django我们是基于python3来演示的.首先我们来安装一下django框架.使用pip3 install django安装的是最新的版本: 我们在pycharm中创建django工程.如图所示: ...

  7. 编写高质量代码改善C#程序的157个建议——建议50:在Dispose模式中应区别对待托管资源和非托管资源

    建议50:在Dispose模式中应区别对待托管资源和非托管资源 真正资源释放代码的那个虚方法是带一个bool参数的,带这个参数,是因为我们在资源释放时要区别对待托管资源和非托管资源. 提供给调用者调用 ...

  8. BZOJ 4034[HAOI2015]树上操作(树链剖分)

    Description 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个操作,分为三种:操作 1 :把某个节点 x 的点权增加 a .操作 2 :把某个节点 x 为根的子树中所有点 ...

  9. LibreOJ 6279 数列分块入门 3(分块+排序)

    题解:自然是先分一波块,把同一个块中的所有数字压到一个vector中,将每一个vector进行排序.然后对于每一次区间加,不完整的块加好后暴力重构,完整的块直接修改标记.查询时不完整的块暴力找最接近x ...

  10. Async异步委托

    /// <summary> /// 异步委托 /// </summary> public delegate void AsyncHandler(); public static ...