C++_异常8-异常、类和基础
异常、类和继承以三种方式相互关联。
首先,可以像标准C++库所做的那样,从一个异常类派生出另一个。
其次,可以在类定义中嵌套异常类声明来组合异常。
第三,这种嵌套声明本身可以被继承,还可以作为基类。
接下来用一个例子进行相关的探索;
以下这个头文件声明了一个Sales类,它用于存储一个年份以及一个包含12个月销售数据的数组。
LabelledSales类是从Sales派生而来的。新增了一个用于存储数据标签的成员。
- //sales.h -- exception and inheritance
- #include <stdexcept>
- #include <string>
- class Sales
- {
- public:
- enum {MONTHS = };
- class bad_index : public std::logic_error
- {
- };
- explicit Sales(int yy = );
- Sales(int yy, const double * gr, int n);
- virtual ~Sales() {}
- int Year() const { return year;}
- virtual double operator[] (int i) const;
- virtual double & operator[] (int i);
- private:
- double gross[MONTHS];
- int year;
- };
- class LabeledSales : public Sales
- {
- public:
- class nbad_index : public Sales::bad_index
- {
- private:
- std::string lbl;
- public:
- nbad_index(const std::string & lb, int ix, const std::string & s = "Index error in LabeledSales object\n");
- const std::string & label_val() const {return lbl;}
- virtual ~nbad_index() throw() {}
- }
- explicit LabeledSales(const std::string & lb = "none", int yy = );
- LabeledSales(const std::string & lb, int yy, const double * gr, int n);
- virtual ~LabeledSales() {}
- const std::string & Label() const {return label;}
- virtual double operator[] (int i) const;
- virtual double & operator[] (int i);
- private:
- std::string label;
- };
分析以下头文件的细节;首先,符号常量位于Sales类的保护部分,这使得派生类能够使用这个值。
接下来,bad_index被嵌套在Sales类的公有部分中,这使得客户类的catch块可以使用这个类作为类型。
注意,在外部使用这个类型时,需要使用Sales::bad_index来标识。这个类是从logic_error类派生而来的,能够存储和报告数组索引的超界值。
nbad_index类被嵌套到LabeledSales的公有部分,这使得客户类可以通过LabeledSales::nbad_index来使用它。
它是从bad_inde类派生而来的,因此nbad_index归根结底也是从logic_error派生而来的。
这两个类都有重载的operator[]()方法,这些方法用于访问存储在对象中的数组元素,并在索引超界时引发异常。
接下来是源文件,是没有声明为内联的方法的实现。
- //sales.cpp --Sales implementation
- #include "sales.h"
- using std::string;
- Sales::bad_index::bad_index(int ix, const string & s)
- : std::logic_error(s), bi(ix)
- {
- }
- Sales::Sales(int yy)
- {
- year = yy;
- for(int i = ; i < Months; ++i)
- gross[i] = ;
- }
- Sales::Sales(int yy, const double * gr, int n)
- {
- year = yy;
- int lim = (n< MONTHS)? n : MONTHS;
- int i;
- for (i=;i<MONTHS;++i)
- gross[i] = gr[i];
- // for i >n and i <MONTHS
- for (;i < MONTHS;++i)
- gross[i] = ;
- }
- double Sales::operator[](int i) const
- {
- if(i< || i>=MONTHS)
- throw bad_index(i);
- return gross[i];
- }
- double & Sales:;operator[] (int i)
- {
- if(i< || i>=MONTHS)
- throw bad_index(i);
- return gross[i];
- }
- LabeledSales::nbad_index::nbad_index(const string & lb, int ix, const string & s):Sales::bad_index(ix,s)
- {
- lbl =lb;
- }
- LabeledSales::LabeledSales(const string & lb, int yy):Sales(yy)
- {
- label=lb;
- }
- LabeledSales::LabeledSales(const string & lb, int yy, const double * gr, int n):Sales(yy, gr, n)
- {
- label = lb;
- }
- double LabeledSales::operator[](int i) const
- {
- if(i< || i>=MONTHS)
- throw nbad_index(Label(), i);
- return Sales::operator[](i);
- }
- double & LabeledSales::operator[](int i)
- {
- if(i< || i>=MONTHS)
- throw nbad_index(Label(), i);
- return Sales::operator[](i);
- }
接下来编写程序运行一下:
- //use_sale.cpp --nested exceptions
- #include <iostream>
- #include "sales.h"
- int main()
- {
- using std::cout;
- using std::cin;
- using std::endl;
- double vals1[] =
- {
- , , , , , ,
- , , , , ,
- };
- double vals[] =
- {
- ,,,,,,
- ,,,,,
- };
- Sales sales1 ();
- LabeledSales sales2();
- cout<<"First try block:\n";
- try
- {
- int i;
- cout<<"Year = "<< sales1.Year() << endl;
- for (i =; i<; ++i)
- {
- cout<<sales1[i]<<' ';
- if (i % == )
- cout<<endl;
- }
- cout<<"Year = "<<sales2.Year()<<endl;
- cout<<"Label = "<<sales2.Label()<<endl;
- for (i = ; i<=; ++i)
- {
- cout<<sales2[i]<<' ';
- if (i % == )
- cout<<endl;
- }
- cout<<"End of try block 1.\n";
- }
- catch(LabeledSales::nbad_index & bad)
- {
- cout<<bad.what();
- cout<<"Company: "<<bad.label_val()<<endl;
- cout<<"bad index: "<<bad.bi_val()<<endl;
- }
- catch(Sales::bad_index & bad)
- {
- cout<<bad.what();
- cout<<"bad index: "<<bad.bi_val()<<endl;
- cout << "\nNext try block:\n";
- try
- {
- sales2[] =37.5;
- sales1[]=;
- cout<<"End of try block 2.\n";
- }
- catch(LabeledSales::nbad_index & bad)
- {
- cout << bad.what();
- cout << "Company:" <<bad.label_val()<<endl;
- cout << "bad index:" << bad.bi_val() << endl;
- }
- catch(Sales::bad_index & bad)
- {
- cout << bad.what();
- cout << "bad.bi_val()"<<endl;
- }
- cout << "done\n";
- return ;
- }
C++_异常8-异常、类和基础的更多相关文章
- 网易云课堂_C++程序设计入门(下)_第9单元:白公曾咏牡丹芳,一种鲜妍独“异常”_第9单元 - 作业5:OJ编程 - 使用异常进行图形类的错误处理
第9单元 - 作业5:OJ编程 - 使用异常进行图形类的错误处理 查看帮助 返回 温馨提示: 1.本次作业属于Online Judge题目,提交后由系统即时判分. 2.学生可以在作业截止时间之前 ...
- Util应用程序框架公共操作类(五):异常公共操作类
任何系统都需要处理错误,本文介绍的异常公共操作类,用于对业务上的错误进行简单支持. 对于刚刚接触.Net的新手,碰到错误的时候,一般喜欢通过返回bool值的方式指示是否执行成功. public boo ...
- python进阶八_警告和异常
心情有点纠结,怎么说呢,倒不是由于其它学习上的事情,反而是由于生活上狗血的剧情逼着人偏离,渐行渐远,人跟人之间有误会也是正常的,可能是由于交流不够,彼此不够了解吧,希望能尽快度过这一段纠结的日子,简单 ...
- springmvc在处理请求过程中出现异常信息交由异常处理器进行处理,自定义异常处理器可以实现一个系统的异常处理逻辑。为了区别不同的异常通常根据异常类型自定义异常类,这里我们创建一个自定义系统异常,如果controller、service、dao抛出此类异常说明是系统预期处理的异常信息。
springmvc在处理请求过程中出现异常信息交由异常处理器进行处理,自定义异常处理器可以实现一个系统的异常处理逻辑. 1.1 异常处理思路 系统中异常包括两类:预期异常和运行时异常RuntimeEx ...
- java异常和错误类总结(2016.5)
看到以前2016.5.写的一点笔记,拿过来放在一起. java异常和错误类总结 最近由于考试和以前的面试经常会遇到java当中异常类的继承层次的问题,弄得非常头大,因为java的异常实在是有点多,很难 ...
- AJPFX关于异常和file类的总结
/** * 各位坛友注意啦!对我这个帖子有任何的疑惑的,可以尽管留帖提问,我会在看到的第一时间回贴,既然写得出这帖子,* 就要对看这帖子的人负责,所以有问题,尽管问!* * * 这块没学好的同学,可以 ...
- _00020 妳那伊抹微笑_谁的异常最诡异第一期之 SqlServer RSA premaster secret error
博文作者:妳那伊抹微笑 博客地址:http://blog.csdn.net/u012185296 博文标题:_00020 妳那伊抹微笑_谁的异常最诡异第一期之 SqlServer RSA premas ...
- java异常继承何类,运行时异常与一般异常的区别
一.基本概念 Throwable是所有异常的根,java.lang.ThrowableError是错误,java.lang.ErrorException是异常,java.lang.Exception ...
- TypeScript完全解读(26课时)_7.ES6精讲 - 类Class基础
ES6精讲 - 类Class基础 es5中创建构造函数和实例 原来在es5中的写法 定义好Point后,在原型对象上定义getPostion的方法 实例自身是没有这个方法的,我们调用的时候会去创建他的 ...
- java多线程系类:基础篇:09之interrupt()和线程终止方式
概要 本章,会对线程的interrupt()中断和终止方式进行介绍.涉及到的内容包括:1. interrupt()说明2. 终止线程的方式2.1 终止处于"阻塞状态"的线程2.2 ...
随机推荐
- PHP json_encode 让URL//不转义
$json_info=json_encode((object)$data,JSON_UNESCAPED_SLASHES);
- Solidity oraclize query apikey加密
solidity 程序中如果用到oraclize query,api调用需要apikey,则最好加密apikey,否则公开solidity代码时会连同apikey一起公开. 加密方法: https:/ ...
- while 和do while循环的区别
int a; scanf_s("%d",&a); while(a>0) { //do something; } while循环先要判断条件是否成立,如果不成立,那么就 ...
- Django rest_framework----序列化组件
生成hypermedialink serializer.pclass BookModelSerializers(serializers.ModelSerializer): class Meta: mo ...
- 数据库MySQL 之 库操作
数据库MySQL 之 库操作 浏览目录 系统数据库简介 数据库操作 命名规范 用户权限 修改密码 忘记密码 中文乱码问题 一.系统数据库简介 information_schema :虚拟库,不占用磁盘 ...
- Django-Web框架之创建项目和应用
Django我们是基于python3来演示的.首先我们来安装一下django框架.使用pip3 install django安装的是最新的版本: 我们在pycharm中创建django工程.如图所示: ...
- 编写高质量代码改善C#程序的157个建议——建议50:在Dispose模式中应区别对待托管资源和非托管资源
建议50:在Dispose模式中应区别对待托管资源和非托管资源 真正资源释放代码的那个虚方法是带一个bool参数的,带这个参数,是因为我们在资源释放时要区别对待托管资源和非托管资源. 提供给调用者调用 ...
- BZOJ 4034[HAOI2015]树上操作(树链剖分)
Description 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个操作,分为三种:操作 1 :把某个节点 x 的点权增加 a .操作 2 :把某个节点 x 为根的子树中所有点 ...
- LibreOJ 6279 数列分块入门 3(分块+排序)
题解:自然是先分一波块,把同一个块中的所有数字压到一个vector中,将每一个vector进行排序.然后对于每一次区间加,不完整的块加好后暴力重构,完整的块直接修改标记.查询时不完整的块暴力找最接近x ...
- Async异步委托
/// <summary> /// 异步委托 /// </summary> public delegate void AsyncHandler(); public static ...