【C++】异常处理 ⑧ ( 标准异常类 | 标准异常类继承结构 | 常用的标准异常类 | 自定义异常类继承 std::exception 基类 )

文章目录

  • 一、抛出 / 捕获 多个类型异常对象
    • 1、标准异常类
    • 2、标准异常类继承结构
    • 3、常用的标准异常类
  • 二、自定义异常类继承 std::exception 基类
    • 1、自定义异常类继承 std::exception 基类
    • 2、完整代码示例 - 自定义异常类继承 std::exception 基类






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




1、标准异常类


在 C++ 语言中 , 提供了一系列的 " 标准异常类 " ,

这些 " 标准异常类 " 都继承了 std::exception 基类 ,

在 标准库 中 , 抛出的异常 , 都是 标准异常类 , 都是 std::exception 类的子类 ;


2、标准异常类继承结构


标准异常类 定义在 std 命名空间 , 标准异常类 基类 std::exception 定义在 <exception> 头文件中 ;

#include <exception>

标准异常类 基类 std::exception 中提供了 what() 函数 , 用于获取异常报错信息 , what 函数的原型如下 :

namespace std {

#pragma warning(push)
#pragma warning(disable: 4577) // 'noexcept' used with no exception handling mode specified
class exception
{
    _NODISCARD virtual char const* what() const
    {
        return _Data._What ? _Data._What : "Unknown exception";
    }
}

标准异常类的继承关系如下图所示 :
在这里插入图片描述

上图中 runtime_error 和 logic_error 两个重要的异常类型基类 ,

  • logic_error 是 编译时 被预先检测出来的异常 , 编程足够规范可以避免此类异常 ; logic_error 定义在了 <stdexcept> 头文件中 , 继承 exception 异常基类 ;
class logic_error : public exception { // base of all logic-error exceptions
  • runtime_error 是 运行时 不能被预先检测出的异常 ; runtime_error 定义在了 <stdexcept> 头文件中 , 继承 exception 异常基类 ;
// CLASS runtime_error
class runtime_error : public exception { // base of all runtime-error exceptions

使用标准异常类 , 使用前需要导入 <stdexcept> 头文件 ;

#include <stdexcept> 

3、常用的标准异常类


常用的标准异常类如下 : std::exception 是标准异常类 基类 , 定义了 what() 函数 , 该方法返回一个指向 C 字符串的指针 , 该字符串包含了描述异常的消息 ;

  • std::bad_alloc : 当无法分配内存时 , 会抛出此异常 ;

  • std::bad_cast : 当进行类型转换时 , 如果转换失败 , 会抛出此异常 ;

  • std::bad_exception : 当异常处理程序无法处理异常时 , 会抛出此异常 ;

  • std::logic_error : 当程序中出现逻辑错误时 , 会抛出此异常 ;

    • std::out_of_range : 当访问超出有效范围的数组元素、vector 或 string 时 , 会抛出此异常 ;
    • std::length_error : 当试图创建一个超过可表示长度的容器时 , 会抛出此异常 ;
    • std::domain_error : 当计算一个数学函数的结果时 , 如果结果不在定义域内 , 会抛出此异常 ;
    • std::invalid_argument : 当一个函数接收到无效的参数时 , 会抛出此异常 ;
  • std::runtime_error : 当程序运行时发生错误时 , 会抛出此异常 ;

    • std::overflow_error : 当整数运算结果太大 , 无法表示时 , 会抛出此异常 ;
    • std::range_error : 当数学函数的结果是无限大或 NaN 时 , 会抛出此异常 ;
    • std::underflow_error : 当数值下溢 , 即数值太小而无法表示时 , 会抛出此异常 ;
  • std::system_error : 当系统调用失败时 , 会抛出此异常 ;

  • std::system_fault : 这是一个用于指示由操作系统引起的错误的异常类 ;

  • std::bad_typeid : 当试图对一个对象使用 typeid 运算符 , 而该对象没有定义 typeid 时 , 会抛出此异常 ;

  • std::bad_weak_ptr : 当使用无效的弱指针时 , 会抛出此异常 ;

  • std::exception_ptr : 这是一个可以持有异常对象的指针类型 ;

  • std::future_error : 当 future 对象的结果未能按预期准备就绪时 , 会抛出此异常 ;

  • std::invalid_promise : 当 future 对象接收到无效的 promise 时 , 会抛出此异常 ;

  • std::lock_error : 当尝试锁定一个已经被锁定的互斥量(mutex)时 , 或者当尝试解锁一个未被锁定的互斥量时 , 会抛出此异常 ;

  • std::mutex_consistent_set : 当使用 std::set_lock_state 设置一个互斥量的状态时 , 如果该状态无效 , 会抛出此异常 ;

  • std::deadlock : 当在两个或更多的线程间产生死锁时 , 会抛出此异常 ;

  • std::unexpected : 当未捕获处理函数中抛出的异常时 , 会抛出此异常 ;





二、自定义异常类继承 std::exception 基类




1、自定义异常类继承 std::exception 基类


首先 , 导入 <stdexcept> 头文件 ;

#include <stdexcept> 

然后 , 自定义类继承 std::exception 类 , 通过构造函数设置异常信息 , 重写 what 函数 , 在该函数中返回异常信息 ;

// 自定义类实现标准异常类基类
class eSize : public exception {
public:
	// 构造函数设置异常信息
	eSize(const char* p)
	{
		this->m_p = p;
	}

	// 重写 what 函数
	virtual const char* what() {
		return m_p;
	}

	// 异常信息
	const char* m_p;
};

再后 , 抛出异常信息 , 都抛出 eSize 类型的自定义异常类信息 , 不再像之前一样 , 抛出多个类型的异常 ;

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

最后 , 捕获并处理异常 , 只需要处理 eSize& 类型的异常即可 ;

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

2、完整代码示例 - 自定义异常类继承 std::exception 基类


代码示例 :

#include <iostream>
#include <stdexcept> 
using namespace std;

// 自定义类实现标准异常类基类
class eSize : public exception {
public:
	// 构造函数设置异常信息
	eSize(const char* p)
	{
		this->m_p = p;
	}

	// 重写 what 函数
	virtual const char* what() {
		return m_p;
	}

	// 异常信息
	const char* m_p;
};

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

int main() {

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

	cout << "try-catch 代码块执行完毕" << endl;

	// 控制台暂停 , 按任意键继续向后执行
	system("pause");

	return 0;
};

执行结果 :

捕获异常 : 参数为 0
try-catch 代码块执行完毕
Press any key to continue . . .

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

万字长文带你搞定MMUTLBTWU

最近一直在学习内存管理&#xff0c;也知道MMU是管理内存的映射的逻辑IP&#xff0c;还知道里面有个TLB。 今天刚刚好看到了几篇前辈的文章&#xff0c;很是不错&#xff0c;于是这里来一起学习一下吧。 PART 一&#xff1a;MMU 架构篇 MMU&#xff08;Memory Management Uni…

线程池(Linux +C/C++)

参考 手写线程池 - C语言版 | 爱编程的大丙 (subingwen.cn) 1.为什么需要线程池&#xff1f; 1&#xff09;线程问题&#xff1a; &#xff08;1&#xff09;如果只使用线程创建函数&#xff0c;在不断有新的任务进来的时候&#xff0c;需要不断的创建任务&#xff1b;任务在…

Temu数据接口:为开发者提供的强大工具

在如今数字化的时代&#xff0c;数据成为了商业运营中不可或缺的一部分。为了满足开发者对数据获取和分析的需求&#xff0c;Temu平台推出了强大的数据接口&#xff0c;为开发者提供了丰富的API服务。通过Temu数据接口&#xff0c;开发者可以方便地获取商品信息、订单数据、用户…

【Avue】select的远程搜索 [模糊搜索]

一、需求 【模糊搜索】 二、实现avue的远程搜索 1、search为搜索 2、remote远程搜索 3、dictValue{{key}}为输入的值

@Scheduled,Quartz,XXL-JOB三种定时任务总结

Scheduled&#xff0c;Quartz&#xff0c;XXL-JOB三种定时任务总结 一、Scheduled 简介 Scheduled 是 Spring 框架中用于声明定时任务的注解。通过使用 Scheduled 注解&#xff0c;你可以指定一个方法应该在何时执行&#xff0c;无需依赖外部的调度器。 这个注解通常与Enab…

python的安装

python官网地址&#xff1a;https://www.python.org/ 以在windows下安装3.12.0版本为例。 下载安装包&#xff1a; 下载下来的安装包是python-3.12.0-amd64.exe&#xff0c;双击安装&#xff0c;按照提示&#xff0c;一步一步往下走&#xff1a; 到cmd下&#xff0c;输入py…

postgresql pg_hba.conf 配置详解

配置文件之pg_hba.conf介绍 该文件用于控制访问安全性&#xff0c;管理客户端对于PostgreSQL服务器的访问权限&#xff0c;内容包括&#xff1a;允许哪些用户连接到哪个数据库&#xff0c;允许哪些IP或者哪个网段的IP连接到本服务器&#xff0c;以及指定连接时使用的身份验证模…

单片机的扩展结构

目录 三种总线的构造方式 地址空间分配和外部地址锁存器 1.存储器地址空间分配 (1)74LS138 (2)74LS139 2.外部地址锁存器 (1)锁存器74LS373 静态数据存储器RAM的并行扩展 (1)常用的静态RAM (SRAM)芯片 (2)外扩数据存储器的读写操作时序 1.读片外RAM操作时序 2.写片…

JDK8新特性——Stream流

文章目录 一、Stream流体验二、Stream流的创建三、Stream流中间方法四、Stream流终究方法 Stream流&#xff08;也叫Stream API&#xff09;。它是从JDK8以后才有的一个新特性&#xff0c;是专业用于对集合或者数组进行便捷操作的 一、Stream流体验 需求&#xff1a;有一个Lis…

【学习笔记】混淆矩阵

混淆矩阵&#xff08;Confusion Matrix&#xff09;&#xff0c;又称为错误矩阵&#xff0c;是一种特别适用于监督学习中分类问题评估模型性能的工具。在机器学习领域&#xff0c;混淆矩阵能够清晰地显示算法模型的分类结果和实际情况之间的差异&#xff0c;常用于二分类和多分…

vscode里面使用vue的一些插件,方便开发

1、vue 2 Snippets &#xff08;vue语法提示&#xff09; vue提示这个也可以 1.1 Vue VSCode Snippets 2、vetur Vetur支持.vue文件的语法高亮显示&#xff0c;除了支持template模板以外 3、Element UI Snippets(饿了么的提示) 4、indent-rainbow&#xff08;缩进高亮提示) 5…

《开箱元宇宙》:Madballs 解锁炫酷新境界,人物化身系列大卖

你是否曾想过&#xff0c;元宇宙是如何融入世界上最具代表性的品牌和名人的战略中的&#xff1f;在本期的《开箱元宇宙》 系列中&#xff0c;我们与 Madballs 的战略顾问 Derek Roberto 一起聊聊 Madballs 如何在 90 分钟内售罄 2,000 个人物化身系列&#xff0c;以及是什么原…

【开源】基于Vue.js的新能源电池回收系统

文末获取源码&#xff0c;项目编号&#xff1a; S 075 。 \color{red}{文末获取源码&#xff0c;项目编号&#xff1a;S075。} 文末获取源码&#xff0c;项目编号&#xff1a;S075。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 用户档案模块2.2 电池品类模块2.3 回…

Nginx(缓存机制)

对于性能优化而言&#xff0c;缓存是一种能够大幅度提升性能的方案&#xff0c;因此几乎可以在各处都能看见缓存&#xff0c;如客户端缓存、代理缓存、服务器缓存等等&#xff0c;Nginx的缓存则属于代理缓存的一种。对于整个系统而言&#xff0c;加入缓存带来的优势额外明显&am…

创新零售巨头:揭开山姆与Costco蓬勃发展背后的秘密

会员制商店这个冷门的业态突然之间硝烟弥漫&#xff0c;更多的资本开始涌向付费会员商店这一业态&#xff0c;本文即将探讨的是付费会员制的成功秘诀和零售企业可行的发展路径。Costco的发展经验对国内超市巨头的崛起具有显著的借鉴意义&#xff0c;以优质低价商品服务为中心&a…

CVE-2016-2510CVE-2017-5586 BeanShell漏洞

前言&#xff1a; 首先我们需要了解BeanShell具体是做什么&#xff1a; BeanShell 是一种轻量级的可嵌入式脚本语言&#xff0c;用于在 Java 环境中执行脚本代码。它提供了一种简单、灵活的方式来扩展和定制 Java 应用程序的行为&#xff0c;允许开发人员动态地执行和评估脚本…

CSS实现瀑布流

多列布局介绍 多列布局 指的是 CSS3 可以将文本内容设计成像报纸一样的多列布局&#xff0c;例&#xff1a; CSS3 的多列布局属性: column-count&#xff1a;指定了需要分割的列数&#xff1b;column-gap&#xff1a;指定了列与列间的间隙&#xff1b;column-rule-style&#…

Mybatis如何执行批量操作

文章目录 Mybatis如何执行批量操作使用foreach标签 使用ExecutorType.BATCH如何获取生成的主键 Mybatis如何执行批量操作 使用foreach标签 foreach的主要用在构建in条件中&#xff0c;它可以在SQL语句中进行迭代一个集合。foreach标签的属性主要有item&#xff0c;index&…

MySQL系统函数

select version();查看mysql版本。 select user();可以查看数据库用户名。 select database();可以查看数据库名。 select system_use();可以查看系统用户名。 show variables like %basedir%;可以展示数据库读取路径。 show variables like %sets_dir%;可以看一下安…

★136. 只出现一次的数字(位运算)

136. 只出现一次的数字 这个题主要考察的知识点是位运算&#xff08;这里是异或&#xff09; 如果不要求空间复杂度为O&#xff08;1&#xff09;&#xff0c;那有很多方法。但是这里有这样的要求。 可以通过位运算 的方法来实现。 异或运算 ⊕有以下三个性质&#xff1a; 任…