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

缺点:

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

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

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

相关文章

2024“源鲁杯“高校网络安全技能大赛-Misc-WP

Round 1 hide_png 题目给了一张图片,flag就在图片上,不过不太明显,写个python脚本处理一下 from PIL import Image ​ # 打开图像并转换为RGB模式 img Image.open("./attachments.png").convert("RGB") ​ # 获取图像…

rabbitmq 使用注意事项

1,注意开启的端口号,一共四个端口号,1883是mqtt连接的端口号,如果没开,是连接不上的需要手动起mqtt插件。 //开始mqtt插件服务 rabbitmq-plugins enable rabbitmq_mqtt 2,15672端口是http网页登录的管理后…

Next Stack技术联盟成立:打造新一代基础软件技术栈

北京,2024 年 10 月 —— 在全球数字化浪潮的推动下,中国基础软件产业迎来了前所未有的创新机遇与挑战。为应对这一时代任务并推动中国基础软件的全球化进程,观测云携手多家领先技术企业正式宣布成立 Next Stack 技术联盟。这一联盟旨在汇聚国…

接口测试(五)jmeter——get请求

一、get请求——短信验证码(示例仅供参考) 1. get请求:传参数据直接拼接在地址后面,jmeter不需要设置请求头content-type 注:短信验证码接口,返回结果中不会返回短信验证码,是存在数据库表中&a…

Maven项目管理工具-初始+环境配置

1. Maven的概念 1.1. 什么是Maven Maven是跨平台的项目管理工具。主要服务于基于Java平台的项目构建,依赖管理和项目信息管理。 理想的项目构建:高度自动化,跨平台,可重用的组件,标准化的流程 maven能够自动下载依…

Mybatis-plus-入门

Mybatis-plus-入门 1&#xff1a;介绍 mybatis-plus的官网&#xff1a;MyBatis-Plus &#x1f680; 为简化开发而生 2: 快速入门 步骤&#xff1a; 1&#xff1a;引入依赖&#xff1a; <dependency><groupId>com.baomidou</groupId><artifactId>my…

STM32使用硬件I2C读写AT24C02 EEPROM(一)

文章目录 一、软件准备配置I2C接口&#xff1a;生成工程代码&#xff1a; 二、编写驱动程序初始化I2C接口&#xff1a;编写读写函数&#xff1a; 三、调试与测试 前面讲到使用软件模拟i2c读写AT24C02&#xff0c;这篇文章使用stm32 提供的硬件i2c读写&#xff0c;看看怎么回事 …

gin入门教程(3):创建第一个 HTTP 服务器

首先设置golang github代理&#xff0c;可解决拉取git包的时候&#xff0c;无法拉取的问题&#xff1a; export GOPROXYhttps://goproxy.io再查看自己的go版本&#xff1a; go version我这里的版本是&#xff1a;go1.23.2 linux/arm64 准备工作做好之后就可以进行开发了 3.…

【AscendC算子开发】笔记1 算子开发哲学

重看这门课&#xff0c;有很多内容的认识更深了&#xff0c;做一些记录。 为什么不能将网络节点融合 这个问题关联到另一个问题&#xff1a;为什么我们需要激活函数&#xff1f; 使用线性的神经元堆叠得到的方程最后也是线性方程&#xff0c;无法表征非线性的信息&#xff0c…

软考(网工)——网络安全

文章目录 &#x1f550;网络安全基础1️⃣网络安全威胁类型2️⃣网络攻击类型 &#x1f551;现代加密技术1️⃣私钥密码/对称密码体制2️⃣对称加密算法总结3️⃣公钥密码/非对称密码4️⃣混合密码5️⃣国产加密算法 - SM 系列6️⃣认证7️⃣基于公钥的认证 &#x1f552;Hash …

Node.js:深入探秘 CommonJS 模块化的奥秘

在Node.js出现之前&#xff0c;服务端JavaScript基本上处于一片荒芜的境况&#xff0c;而当时也没有出现ES6的模块化规范。因此&#xff0c;Node.js采用了当时比较先进的一种模块化规范来实现服务端JavaScript的模块化机制&#xff0c;它就是CommonJS&#xff0c;有时也简称为C…

react18中使用redux管理公共数据仓库实现数据immutable更新

Immutable.js出自Facebook&#xff0c;是最流行的不可变数据结构的实现之一。它实现了完全的持久化数据结构&#xff0c;使用结构共享。所有的更新操作都会返回新的值&#xff0c;但是在内部结构是共享的&#xff0c;来减少内存占用。Immutablejs官网 在上一篇介绍redux的文章&…

数字IC后端实现 | Innovus各个阶段常用命令汇总

应各位读者要求&#xff0c;小编最近按照Innovus流程顺序整理出数字IC后端项目中常用的命令汇总。限于篇幅&#xff0c;这次只更新到powerplan阶段。有了这份Innovus常用命令汇总&#xff0c;学习数字IC后端从此不再迷路&#xff01;如果大家觉得这个专题还不错&#xff0c;想继…

实验:使用Oxygen发布大型手册到Word格式

此前&#xff0c;我曾发表过一篇文章《结构化文档发布的故事和性能调优》&#xff0c;文中讨论了在将大型DITA手册转换为PDF格式时可能遇到的性能挑战及相应的优化策略。 近日&#xff0c;有朋友咨询&#xff0c;若将同样的大型手册输出为MS Word格式&#xff0c;是否也会面临…

MongoDB Shell 基本命令(三)生成学生脚本信息和简单查询

一、生成学生信息脚本 利用该脚本可以生成任意个学生信息&#xff0c;包括学号、姓名、班级、年级、专业、课程名称、课程成绩等信息&#xff0c;此处生成2万名学生&#xff0c;学生所有信息都是给定范围后随机生成。 生成学生信息后&#xff0c;再来对学生信息进行简单查询。…

Java 开发——(上篇)从零开始搭建后端基础项目 Spring Boot 3 + MybatisPlus

一、概述 记录时间 [2024-10-23] 本文是一个基于 Spring Boot 3 MybatisPlus 的项目实战开发&#xff0c;主要涵盖以下几个方面&#xff1a; 从零开始的项目创建IDEA 中开发环境的热部署Maven、Swagger3、MybatisPlus 等的配置路由映射知识静态资源访问文件上传功能实现拦截器…

探寻闲鱼libsgmain加解密算法(4) ——JNI入口跳转

关注我的人都知道我一直在学习阿里的加密和算法&#xff0c;除了研究逆向问题&#xff0c;还会把学来的阿里技术用在自己的应用上。 为什么&#xff1f;因为学习大厂的应用&#xff0c;是进步最快的方法。而大厂在安全和加密方面的技术&#xff0c;个人觉得阿里做的是最好的。 …

个体能量的勇气层级是否容易达到?

没有勇气面对现实&#xff0c;没有勇气改变自我&#xff0c;没有勇气改变环境&#xff0c;没有勇气创新创造。 这是常态。 如何找寻高质量免费机器人工程资源自学提升-CSDN博客 个人能力的提升&#xff0c;也包括个体能量的提升。 个体能量是个人能力的一个非常重要的衡量指…

Spring Boot整合Stripe订阅支付指南

在当今的在线支付市场中&#xff0c;Stripe 作为一款一体化的全球支付平台&#xff0c;因其易用性和广泛的支付方式支持&#xff0c;得到了许多企业的青睐。本文将详细介绍如何在 Spring Boot 项目中整合 Stripe 实现订阅支付功能。 1.Stripe简介 Stripe 是一家为个人或公司提…

C语言实现Go的defer功能

之前笔者写了一篇博文C实现Go的defer功能&#xff0c;介绍了如何在C语言中实现Go的defer功能&#xff0c;那在C语言中是否也可以实现这样的功能呢&#xff1f;本文就将介绍一下如何在C语言中实现Go的defer功能。 我们还是使用C实现Go的defer功能中的示例&#xff1a; void te…