C++ 抛异常

目录

一.抛异常与运行崩溃的区别

1.运行崩溃

2.抛异常

二.抛异常机制存在的意义

1.清晰的处理错误

2.结构化的错误管理

3.跨函数传递错误信息

4.异常对象多态性

三.抛异常的使用方法

1.抛出异常 (throw)

2.捕获异常 (catch)

3.标准异常类

四.抛异常的处理机制

1.抛异常在函数调用链中的匹配规则

2.throw 与 catch 的细节问题

3.异常的重新抛出


一.抛异常与运行崩溃的区别

1.运行崩溃

运行崩溃是指程序在执行过程中由于某种无法恢复的错误而突然终止(这种情况是不受控的)。

原因

①非法内存访问:尝试访问未分配或已释放的内存。

②空指针解引用:使用值为 nullptr 的指针。

③栈溢出:函数调用层次过深或局部变量占用过多栈空间。

④操作系统资源不足:如内存、文件句柄等耗尽。

⑤编译器或链接器生成的错误代码。

程序崩溃的结果:程序无法继续执行,通常会显示错误消息或生成核心转储文件

2.抛异常

抛异常是程序中的一种受控的错误处理机制(即这种情况是我们已经提取预料到了的)。当程序遇到无法处理的错误或异常情况时,可以抛出一个异常对象,并跳到异常处理代码(即catch块)。

原因:

如除数为0、内存分配失败(new可能失败并抛出 std::bad_alloc 异常)、数组越界等。

抛异常的结果:如果异常被正确处理,程序可以继续执行。如果异常没有被捕捉,程序将调用terminate() 并终止。

小结

运行崩溃是程序由于无法恢复的错误而突然终止的情况。它通常是由于严重的运行时问题导致的。

抛异常是程序中的一种受控的错误处理机制。它允许程序在遇到错误时抛出异常对象,并将控制权转移到异常处理代码。如果异常被正确处理,程序可以继续执行;否则,程序将终止。

我们应该尽量避免运行崩溃,并通过抛异常和其他错误处理机制来优雅地处理潜在的错误情况。

二.抛异常机制存在的意义

1.清晰的处理错误

抛异常机制允许程序在运行时遇到错误或异常情况时,能够优雅地处理这些错误,而不是简单地崩溃或返回错误码。

2.结构化的错误管理

抛异常允许程序跳转到特定的错误处理代码块(即catch块),这使得错误恢复更加结构化和易于管理,程序可以在捕获异常后执行特定的清理操作,然后恢复执行。

3.跨函数传递错误信息

使用抛异常可以减少嵌套的错误检查代码,异常可以在函数之间传播,甚至可以在不同的模块或库之间传播。

4.异常对象多态性

异常对象可以是派生自std::exception的自定义异常类,这使得异常处理可以支持多态性。通过捕获基类异常(如std::exception),程序可以处理多种类型的异常,而无需为每个可能的异常类型编写单独的catch块。

三.抛异常的使用方法

1.抛出异常 (throw)

当程序检测到某种错误或异常情况时,我们可以使用 throw 关键字抛出一个异常,或者将可能出错的代码放在 try 块中,抛出的异常可以是任何类型的对象,但通常是继承自 std::exception 的标准异常类或用户自定义的异常类。

2.捕获异常 (catch)

使用 try 块包裹可能抛出异常的代码,然后在随后的 catch 块中捕获并处理这些异常,我们可以定义多个 catch 块来捕获不同类型的异常。

3.标准异常类

std::exception:所有标准异常的基类。

std::bad_alloc:内存分配失败时抛出。

std::bad_cast:在动态类型转换失败时抛出(例如,使用dynamic_cast)。

std::bad_exception:当无法处理一个通过throw抛出的异常时抛出(用于函数声明为throw(type))。

std::invalid_argument:传递给函数的参数无效时抛出。

std::length_error:试图创建一个超出允许长度的对象时抛出(例如,std::string)。

std::out_of_range:使用一个超出有效范围的值时抛出(例如,数组索引越界)。

std::overflow_error:算术运算结果上溢时抛出。

std::range_error:当函数结果超出其有效范围时抛出(不是标准异常类的一部分,但通常在标准库中与overflow_error和underflow_error一起讨论)。

std::runtime_error:在运行时发生异常时抛出(如运行时检测到的逻辑错误)。

std::underflow_error:算术运算结果下溢时抛出。

四.抛异常的处理机制

1.抛异常在函数调用链中的匹配规则

a.首先检查throw本身是否在try内部,如果不在,则程序立即终止(抛异常);如果在,就查找匹配的catch语句,如果当前栈帧有匹配的catch,则直接进入该catch内部。

b.如果当前栈帧内没有匹配的catch,则退出当前函数栈,回到上层函数栈中进行查找catch,若仍没有,则继续向上层栈帧去找。

c.如果到达main函数的栈,依旧没有找到catch,则终止程序,运行报错!

d.找到匹配的catch子句(catch参数类型匹配)并处理后,会继续沿着catch子句向后继续执行

2.throw 与 catch 的细节问题

a.异常通过抛出对象而引发的,抛出对象的类型决定了应该匹配哪个catch的处理代码

b.throw所匹配的catch是函数调用链中与抛出对象类型匹配且离抛异常位置最近的那一个。

c.抛出异常对象后,会生成一个异常对象的拷贝,因为抛出的异常对象可能是一个临时对象,所以会生成一个拷贝对象,这个拷贝出来的临时对象会在catch后销毁。

d.catch(. . .)可以捕获任意类型的异常,但就是不知道异常错误是什么,它通常用来兜底~~

3.异常的重新抛出

异常的重新抛出是指在 catch 块中捕捉到异常后,不是直接处理它,而是使用 throw 语句将其再次抛出。重新抛出的异常可以是原异常(即捕捉到的那个异常对象),也可以是一个新的异常对象。重新抛出异常通常用于在多层函数调用中传递异常信息,或者在 catch 块中执行了一些清理操作后需要让上层调用者处理异常。

如:

异常安全

①构造函数完成对象的构造和初始化,最好不要在构造函数中抛异常,否则可能导致对象不完整或没有完全初始化

②析构函数主要完成资源的清理,最好不要在析构函数内抛异常,否则可能导致资源泄漏

异常的优缺点

优点:

1.异常对象定义好了,相比错误码的方式,前者可以清晰准确的显示出错误的各种信息,甚至可以包含堆栈调用的信息,帮助更好的定位程序bug

2.传统错误码的返回方式最大问题就是:在函数调用链中,深层的函数返回错误,那么我们得层次返回错误,最外层才能拿到错误!

缺点:

执行流乱跳、混乱,分析程序时难以跟踪!

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

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

相关文章

【MySQL备份】Percona XtraBackup

这份文档针对的是最新发布的版本:Percona XtraBackup 2.4.29(发布说明)。 Percona XtraBackup是一款针对MySQL系列服务器的开源热备份工具,在备份过程中不会锁定您的数据库。它能够对MySQL 5.1、5.5、5.6和5.7服务器以及带有Xtra…

UDP传输协议Linux C语言实战

文章目录 1.UDP简介1.1特点1.2 UDP协议头部格式1.2.1 **UDP头部**:1.2.2 **头部意义**:1.2.3 **头部参数**: 1.3 UDP数据长度控制1.4 UDP协议建立框架 2. 函数介绍2.1 sendto函数2.2 recvform函数2.3 其他函数 3.实例3.1 通用结构体、IPV4结构…

转置卷积的一些理解

转置卷积 当图像输入到卷积网络中,最终生成的特征图的宽高会减小 在语义分割中标签和原始图像大小一致,若输出宽高减小,不利于标签比对 于是使用转置卷积将图像宽高还原 在卷积的时候,通常输入大于输出,可根据输入大小…

【Linux】waitpid函数 及其 非阻塞等待和阻塞等待

父进程等待子进程结束可以通过两种方式实现:阻塞等待和非阻塞等待。这两种方式各有优缺点,适用于不同的场景。 简单来说: 阻塞等待:先等你,我再继续 非阻塞等待:不等你,我继续做自己的事&…

使用Python实现某易云音乐歌曲下载

前言 在这篇文章中,我们将探讨如何通过Python结合JavaScript代码来逆向网易云音乐的API接口,以获取并下载指定歌曲。请注意,本文仅用于技术学习与交流目的,实际使用时请遵守相关法律法规及服务条款。 目标网站 1. 准备工作 首先,我们需要安装一些必要的库: execjs:用…

NVIDIA RTX 5080移动版GPU真身首曝!全系要用GDDR7

英伟达下一代移动版GPU的神秘面纱似乎正在揭开,Moore’s Law is Dead的最新视频首次曝光了疑似RTX 5080移动版GPU的工程样品照片。 这款工程样品印有N22W-ES-A1,与Clevo的下一代笔记本主板规格表相匹配,表明该芯片确实基于NVIDIA的下一代芯片…

java 提示 避免用Apache Beanutils进行属性的copy。

避免用Apache Beanutils进行属性的copy。 Inspection info: 避免用Apache Beanutils进行属性的copy。 说明:Apache BeanUtils性能较差,可以使用其他方案比如Spring BeanUtils, Cglib BeanCopier。 TestObject a new TestObject(); TestObject b new Te…

Cadence元件A属性和B属性相互覆盖

最近在使用第三方插件集成到Cadence,协助导出BOM到平台上,方便对BOM进行管理和修改,结果因为属性A和属性B不相同,导致导出的BOM错误。如下图: ​​ 本来我们需要导出Q12,结果给我们导出了Q13,或者反之&…

SpringBoot实现的高效民宿预订平台

2相关技术 2.1 MYSQL数据库 MySQL是一个真正的多用户、多线程SQL数据库服务器。 是基于SQL的客户/服务器模式的关系数据库管理系统,它的有点有有功能强大、使用简单、管理方便、安全可靠性高、运行速度快、多线程、跨平台性、完全网络化、稳定性等,非常…

AWD的复现

学习awd的相关资料:速成AWD并获奖的学习方法和思考记录- Track 知识社区 - 掌控安全在线教育 - Powered by 掌控者(包含使用脚本去批量修改密码) 在复现之前去了解了以下AWD的相关脚本 资料:AWD批量攻击脚本使用教程-CSDN博客 …

13_渲染器的设计

目录 渲染器与响应式系统的结合渲染器的基本概念自定义渲染器 渲染器与响应式系统的结合 渲染器与响应式系统是相辅相成的,渲染器负责将响应式系统中的响应式数据渲染到视图中,而响应式系统则负责监听数据的变化并通知渲染器进行更新。 渲染器在浏览器…

大数据-184 Elasticsearch - 原理剖析 - DocValues 机制原理 压缩与禁用

点一下关注吧!!!非常感谢!!持续更新!!! 目前已经更新到了: Hadoop(已更完)HDFS(已更完)MapReduce(已更完&am…

在 Docker 中搭建 PostgreSQL16 主从同步环境

1. 环境搭建 本文介绍了如何在同一台机器上使用 Docker 容器搭建 PostgreSQL 的主从同步环境。通过创建互联网络和配置主库及从库,详细讲解了数据库初始化、角色创建、数据同步和验证步骤。主要步骤包括设置主库的连接信息、创建用于复制的角色、使用 pg_basebacku…

成都跃享未来教育咨询有限公司抖音小店新生态

在数字化浪潮席卷全球的今天,教育行业正经历着前所未有的变革与升级。作为一座历史悠久而又充满活力的城市,成都凭借其深厚的文化底蕴和前瞻性的发展眼光,孕育了众多创新型企业。其中,成都跃享未来教育咨询有限公司(以…

计算机专业大学四年的学习路线(非常详细),零基础入门到精通,看这一篇就够了

前言 许多学子选择踏上计算机这条充满挑战与机遇的道路。但在大学四年中,如何规划自己的学习路线,才能在毕业时脱颖而出,成为行业的佼佼者呢? 第一学年:基础知识的奠基 1.1 课程安排 在大学的第一年,重…

spark:Structured Streaming介绍

文章目录 1. Structured Streaming介绍1.1 实时计算和离线计算1.1.1 实时计算1.1.2 离线计算 1.2 有界和无界数据 2. 简单使用3. 编程模型4. 数据处理流程4.1 读取数据Source4.1.1 文件数据处理 4.2 计算操作 Operation4.3 数据输出 Sink4.3.1 输出模式4.3.2 指定输出位置4.3.3…

JVM篇(运行时数据区(实战课程学习总结)

目录 学习前言 一、运行时数据区 1. JVM运行时数据区规范 2. Hotspot运行时数据区 3. 分配JVM内存空间 分配堆的大小 分配方法区的大小 分配线程空间的大小 二、程序计数器 1. 作用 2. 存储的数据 3. 异常 三、Java虚拟机栈 1. 栈帧 1.1. 局部变量表 存储内容 …

【已解决】C# NPOI如何在Excel文本中增加下拉框

前言 上图&#xff01; 解决方法 直接上代码&#xff01;&#xff01;&#xff01;&#xff01;综合了各个大佬的自己修改了一下&#xff01;可以直接规定在任意单元格进行设置。 核心代码方法块 #region Excel增加下拉框/// <summary>/// 增加下拉框选项/// </s…

12. 命令行

Hyperf 的命令行默认由 hyperf/command 组件提供&#xff0c;而该组件本身也是基于 symfony/console 的抽象。 一、安装 通常来说该组件会默认存在&#xff0c;但如果您希望用于非 Hyperf 项目&#xff0c;也可通过下面的命令依赖 hyperf/command 组件。 composer require hype…

使用 Spring 框架构建 MVC 应用程序:初学者教程

Spring Framework 是一个功能强大、功能丰富且设计精良的 Java 平台框架。它提供了一系列编程和配置模型&#xff0c;旨在简化和精简 Java 中健壮且可测试的应用程序的开发过程。 人们常说 Java 太复杂了&#xff0c;构建简单的应用程序需要很长时间。尽管如此&#xff0c;Jav…