【C++】异常处理 ⑦ ( 异常类的继承层次结构 | 抛出 / 捕获 多个类型异常对象 | 抛出子类异常对象 / 捕获并处理 父类异常对象 )

文章目录

  • 一、抛出 / 捕获 多个类型异常对象
    • 1、抛出 / 捕获 多个类型异常对象
    • 2、操作弊端
    • 3、完整代码示例
  • 二、异常类的继承层次结构
    • 1、抛出子类异常对象 / 捕获并处理 父类异常对象
    • 2、完整代码示例 - 抛出子类异常对象 / 捕获并处理 父类异常对象


自定义的 异常类 , 可能存在 继承结构 ,

也就是说 在 同一个 try-catch 代码块中 , 如果需要 拦截 和 处理多个 异常时 ,

如果 这些异常都继承相同的父类 , 只需要拦截一个 父类异常即可 ,

本篇博客中 , 讨论 抛出 / 捕获 的 异常类 存在 继承结构 的情况 ;





一、抛出 / 捕获 多个类型异常对象




1、抛出 / 捕获 多个类型异常对象


定义一个函数 , 传入一个 int 类型的参数 , void fun(int a) , 判定传入的参数值大小 ;

只有参数为 60 的时候 , 符合要求 , 其它情况下 , 一律抛出异常 ,

  • 如果参数为负数 , 抛出 eNegative 异常 ;
  • 如果参数为 0 , 抛出 eZero 异常 ;
  • 如果参数 小于 60 , 抛出 eTooSmall 异常 ;
  • 如果参数 大于 60 , 抛出 eTooBig 异常 ;

首先 , 定义上述异常类 , 定义 4 个 自定义异常类 ;

class eNegative {};
class eZero {};
class eTooBig {};
class eTooSmall {};

然后 , 在函数中 , 根据不同的判断 , 抛出不同的异常 ,

// 1. 在 函数 中 抛出异常
void fun(int a) {// 判定数字大小, 只有 60 时是合法的// 只要传入的参数不是 60 就需要抛出不同的异常if (a == 60) {// 合法}else if (a < 0) {throw eNegative();}else if (a == 0) {throw eZero();}else if (a < 60) {throw eTooSmall();}else if (a > 60) {throw eTooBig();}
}

最后 , 在 try-catch 代码块中 , 捕获异常 , 需要将 4 个异常 , 各自捕获一次 ;

	// 2. 捕获并处理异常try{// 调用可能产生异常的函数fun(0);}catch (eNegative& e) {cout << "参数是负数" << endl;}catch (eZero & e) {cout << "参数是 0" << endl;}catch (eTooSmall & e) {cout << "参数太小" << endl;}catch (eTooBig & e) {cout << "参数太大" << endl;}catch (...) {cout << "未知异常" << endl;}

2、操作弊端


上述操作 , 有一个弊端 , 那就是每次拦截处理异常时 , 都要手动编写多个 catch 分支 , 每个 catch 分支都要进行各自的操作 ;

如果要在多个位置 , 拦截处理异常 , 则需要编写的代码就太多了 ; 后期维护起来很复杂 ;


3、完整代码示例


代码示例 :

#include "iostream"
using namespace std;class eSize {};
class eNegative {};
class eZero {};
class eTooBig {};
class eTooSmall {};// 1. 在 函数 中 抛出异常
void fun(int a) {// 判定数字大小, 只有 60 时是合法的// 只要传入的参数不是 60 就需要抛出不同的异常if (a == 60) {// 合法}else if (a < 0) {throw eNegative();}else if (a == 0) {throw eZero();}else if (a < 60) {throw eTooSmall();}else if (a > 60) {throw eTooBig();}
}int main() {// 2. 捕获并处理异常try{// 调用可能产生异常的函数fun(0);}catch (eNegative& e) {cout << "参数是负数" << endl;}catch (eZero & e) {cout << "参数是 0" << endl;}catch (eTooSmall & e) {cout << "参数太小" << endl;}catch (eTooBig & e) {cout << "参数太大" << endl;}catch (...) {cout << "未知异常" << endl;}cout << "try-catch 代码块执行完毕" << endl;// 控制台暂停 , 按任意键继续向后执行system("pause");return 0;
};

执行结果 :

参数是 0
try-catch 代码块执行完毕
请按任意键继续. . .

在这里插入图片描述





二、异常类的继承层次结构




1、抛出子类异常对象 / 捕获并处理 父类异常对象


如果 抛出 / 捕获 多个类型的异常对象 , 每次拦截处理异常时 , 都要手动编写多个 catch 分支 , 不利于代码维护 ;

如果将 相似类型的异常 都继承自 一个父类 , 那么每次拦截时 , 只需要拦截一个父类异常即可 ;


定义父类异常 , 其中定义一个纯虚函数 , 该纯虚函数是异常打印 , 或者异常处理的通用操作 ;

class eSize {
public:virtual void printError() = 0;
};

剩余的 4 个异常类 , 都继承 异常类父类 , 并实现纯虚函数 ;

class eNegative : public eSize {
public:virtual void printError() {cout << "参数是负数" << endl;}
};
class eZero : public eSize {
public:virtual void printError() {cout << "参数是 0" << endl;}
};
class eTooBig : public eSize {
public:virtual void printError() {cout << "参数太大" << endl;}
};
class eTooSmall : public eSize {
public:virtual void printError() {cout << "参数太小" << endl;}
};

上述定义的纯虚函数 , 会发生多态 ;

在拦截父类对象时 , 调用不同的 异常对象 , 会分别调用不同子类的 虚函数方法 ;


抛出异常的函数如下 , 抛出异常时 , 需要抛出子类异常对象 ;

// 1. 在 函数 中 抛出异常
void fun(int a) {// 判定数字大小, 只有 60 时是合法的// 只要传入的参数不是 60 就需要抛出不同的异常if (a == 60) {// 合法}else if (a < 0) {throw eNegative();}else if (a == 0) {throw eZero();}else if (a < 60) {throw eTooSmall();}else if (a > 60) {throw eTooBig();}
}

捕获并处理异常时 , 只需要拦截 父类异常对象即可 ;

	// 2. 捕获并处理异常try{// 调用可能产生异常的函数fun(0);}catch (eSize& e) {e.printError();}catch (...) {cout << "未知异常" << endl;}

2、完整代码示例 - 抛出子类异常对象 / 捕获并处理 父类异常对象


代码示例 :

#include "iostream"
using namespace std;class eSize {
public:virtual void printError() = 0;
};
class eNegative : public eSize {
public:virtual void printError() {cout << "参数是负数" << endl;}
};
class eZero : public eSize {
public:virtual void printError() {cout << "参数是 0" << endl;}
};
class eTooBig : public eSize {
public:virtual void printError() {cout << "参数太大" << endl;}
};
class eTooSmall : public eSize {
public:virtual void printError() {cout << "参数太小" << endl;}
};// 1. 在 函数 中 抛出异常
void fun(int a) {// 判定数字大小, 只有 60 时是合法的// 只要传入的参数不是 60 就需要抛出不同的异常if (a == 60) {// 合法}else if (a < 0) {throw eNegative();}else if (a == 0) {throw eZero();}else if (a < 60) {throw eTooSmall();}else if (a > 60) {throw eTooBig();}
}int main() {// 2. 捕获并处理异常try{// 调用可能产生异常的函数fun(0);}catch (eSize& e) {e.printError();}catch (...) {cout << "未知异常" << endl;}cout << "try-catch 代码块执行完毕" << endl;// 控制台暂停 , 按任意键继续向后执行system("pause");return 0;
};

执行结果 :

参数是 0
try-catch 代码块执行完毕
请按任意键继续. . .

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/259553.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

canvas绘制运动的圆

代码实现&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdev…

JAVA实现敏感词高亮或打码过滤:sensitive-word

练手项目中实现发表文章时检测文章是否带有敏感词&#xff0c;以及对所有敏感词的一键过滤功能 文章目录 效果预览实现步骤 效果预览 随便复制一篇内容到输入框 机器审核文章存在敏感词&#xff0c;弹消息提示并进入人工审核阶段&#xff08;若机器审核通过&#xff0c;则无需审…

二叉树的非递归遍历(详解)

二叉树非递归遍历原理 使用先序遍历的方式完成该二叉树的非递归遍历 通过添加现有项目的方式将原来编写好的栈文件导入项目中 目前项目存在三个文件一个头文件&#xff0c;两个cpp文件&#xff1a; 项目头文件的代码截图&#xff1a;QueueStorage.h 项目头文件的代码&#xff…

微信小程序 - PC端选择ZIP文件

微信小程序 - PC端选择文件 分享代码片段场景分析解决思路附魔脚本chooseMediaZip 选择附魔后的ZIP文件相关方法测试方法 参考资料 分享代码片段 不想听废话的&#xff0c;直接看代码。 https://developers.weixin.qq.com/s/UL9aojmn7iNU 场景分析 如果你的微信小程序需要选…

pytorch-mask-rcnn 官方

This is a Pytorch implementation 实现 of Mask R-CNN that is in large parts based on Matterports Mask_RCNN. Matterports repository is an implementation on Keras and TensorFlow. The following parts of the README are excerpts 摘录 from the Matterport README. …

汽车电子智能保险丝解决方案

一、背景知识 在过去的几十年里&#xff0c;电子在汽车系统创新中发挥了关键作用。新型半导体器件具有新颖的功能&#xff0c;增强了车辆机械系统提供的功能。 虽然半导体解决方案和电子产品将继续在汽车电子产品中发挥关键作用&#xff0c;但展望未来&#xff0c;汽车创新将…

强大的多平台数据同步工具:SyncMate for Mac

SyncMate for Mac是一个简单易用的应用程序&#xff0c;它可以让你在Mac、iOS设备、Android设备和其他外部存储设备之间同步数据。无论你是要同步联系人、日历、音乐、视频、照片还是其他文件&#xff0c;SyncMate都能够轻松帮你完成。 这个应用程序不仅可以实现设备之间的同步…

UE4 透明物体不渲染显示??

问题描述&#xff1a;半透明特效在背景&#xff08;半透明材质模型&#xff09;前&#xff0c;当半透明特效开始移动的时候&#xff0c;随着速度的加快会逐渐不渲染&#xff01; 解决办法&#xff1a; 1.设置透明度排序 2.如果还没效果&#xff0c;修改半透明背景模型以下材质…

Ubuntu系统使用快速入门实践(七)——软件安装与使用(3)

Ubuntu系统使用快速入门实践系列文章 下面是Ubuntu系统使用系列文章的总链接&#xff0c;本人发表这个系列的文章链接均收录于此 Ubuntu系统使用快速入门实践系列文章总链接 下面是专栏地址&#xff1a; Ubuntu系统使用快速入门实践系列文章专栏 文章目录 Ubuntu系统使用快速…

在工作中灵活运用CHATGPT

问CHAT&#xff1a;基于微课技术的小学创新课堂教学模式开题&#xff0c;重要变更&#xff0c;侧重说明对照课题申请书、根据评议专家意见所作的研究计划调整 CHAT回复&#xff1a;在本研究项目的开题阶段&#xff0c;我们设想通过利用微课技术来提高小学创新课堂的教学质量。 …

医院信息系统源码,采用JAVA编程,支持跨平台部署应用,满足一级综合医院(专科二级及以下医院500床)的日常业务应用

医院HIS系统源码&#xff0c;HIS系统全套源码&#xff0c;支持电子病历4级&#xff0c;自主版权 his医院信息系统内设门诊/住院医生工作站、门诊/住院护士工作站。各工作站主要功能依据职能要求进行研发。如医生工作站主要功能为编辑电子病历、打印、处理医嘱&#xff1b;护士工…

pyside/qt03——人机协同的编程教学—直接面向chatGPT实战开发(做中学,事上练)

先大概有个草图框架&#xff0c;一点点丰富 我纠结好久&#xff0c;直接用Python写UI代码 还是用designer做UI 再转Python呢&#xff0c; 因为不管怎么样都要转成Python代码&#xff0c; 想了想还是学一下designer吧&#xff0c;有个中介&#xff0c;有直观理解。 直接这样也可…