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

首先,可以像标准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-异常、类和基础的更多相关文章

  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. SpringCloud03 Ribbon知识点、 Feign知识点、利用RestTemplate+Ribbon调用远程服务提供的资源、利用feign调用远程服务提供的资源、熔断

    1 远程服务资源的调用 1.1 古老的套路 在微服务出现之前,所有的远程服务资源必须通过RestTemplate或者HttpClient进行:但是这两者仅仅实现了远程服务资源的调用,并未提供负载均衡实 ...

  2. 468C Hack it!

    传送门 题目大意 分析 here 对于最后求p的过程我想再说一下 那个45就是最前一位分别是0~9,所以总贡献就是45乘上每一种数开头对应多少种情况 而后面的10则是他前面可以填多少不同的数对他做的贡 ...

  3. hibernate mapping文件中 xmlns会导致linq to xml 查询不到对应的节点

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  4. Java日志组件logback使用:加载非类路径下的配置文件并设置定时更新

    Java日志组件logback使用:加载非类路径下的配置文件并设置定时更新 摘自: https://blog.csdn.net/johnson_moon/article/details/7887449 ...

  5. Oracle——SQL基础

    一.SQL语句分为以下三种类型: DML: Data Manipulation Language 数据操纵语言DDL: Data Definition Language 数据定义语言DCL: Data ...

  6. css溢出文本显示省略号

    css div { width: 200px; height: 200px; border: 1px solid; /* 以下四条缺一不可 其中 display:block 为隐藏条件 */ disp ...

  7. .Net插入大批量数据

    1. 使用SqlDataAdapter /// <summary>        /// 实现数据库事务,大批量新增数据        /// </summary>       ...

  8. zend studio中安装Emmet插件后迅速编写html的方法

    table>tr*3>th*1+td*3h1{hello}            <h1>hello</h1>a[href="xx.xxx.xxx(网址) ...

  9. JQuery中一些常用函数的运用

    一.JQuery的效果介绍 二.定时弹出广告图片JQ部分代码 <script type="text/javascript"> var time; $(function( ...

  10. .net在线HTML编辑器

    //在线网页编辑器, <script> var editor2 = new baidu.editor.ui.Editor({//实例化编辑器 initialContent: '', min ...