C++异常

2023-11-17

概念

C语言处理异常的方式:

  1. 终止程序
  2. 返回错误码,很多系统的库函数就是使用这中方式。

C++异常: 异常是一种处理错误的方式,当一个函数发现自己无法处理的错误时就可以抛出异常,让函数的直接或间接的调用者处理这个错误。

  • throw: 当问题出现时,程序会抛出一个异常。这是通过使用 throw 关键字来完成的。
  • catch: 在您想要处理问题的地方,通过异常处理程序捕获异常.catch 关键字用于捕获异常,可以有多个catch进行捕获。
  • try: try 块中的代码标识将被激活的特定异常,它后面通常跟着一个或多个 catch
try
{
	// 保护的标识代码,在其中抛出异常
}catch( ExceptionName e1 )
{
	// catch 块
}catch( ExceptionName e2 )
{
	// catch 块
}catch( ExceptionName eN )
{
	// catch 块
}

异常的抛出

  1. 异常是通过抛出对象而引发的,该对象的类型决定了被哪个catch捕捉并进行处理。
  2. 异常会被在调用链中的距离最近的对象类型匹配的catch块捕捉
  3. 抛出异常对象后,会生成一个异常对象的拷贝,因为抛出的异常对象可能是一个临时对象,所以会生成一个拷贝对象,这个拷贝的临时对象会在被catch以后销毁。(类似于函数的传值返回)
  4. catch(...)可以捕获任意类型的异常,问题是不知道异常错误是什么。可以当做保底措施
  5. 实际中抛出和捕获的匹配原则有个例外,并不都是类型完全匹配,可以抛出的派生类对象,使用基类捕获。

在函数调用链中异常栈展开匹配原则:

  1. 首先检查throw本身是否在try块内部,如果是再查找匹配的catch语句。如果有匹配的,则调到catch的地方进行处理。
  2. 没有匹配的catch则退出当前函数栈,继续在调用函数的栈中进行查找匹配的catch
  3. 如果到达main函数的栈,依旧没有匹配的,则终止程序。上述这个沿着调用链查找匹配的catch子句的过程称为栈展开。所以实际中我们最后都要加一个catch(...)捕获任意类型的异常,否则当有异常没捕获,程序就会直接终止。
  4. 找到匹配的catch子句并处理以后,会继续沿着catch子句后面继续执行。
    在这里插入图片描述

异常的重新抛出

成功捕捉异常之后,可能需要交给更外层的的调用链函数来进行处理,则可以在catch块中将异常重新抛出:

catch(...)
{
	throw; 	// 重新抛出
}

异常安全

  1. 最好不要在析构或者构造函数中抛出异常,否则可能导致对象不完整或者没有完成初始化,或者造成内存泄漏等问题。
  2. 抛出异常经常会导致资源泄漏问题:比如在newdelete中抛出了异常,导致内存泄漏,在lockunlock之间抛出了异常导致死锁。内存泄漏可以借助RAII的智能指针解决。

异常规范

  1. 异常规格说明的目的是为了让函数使用者知道该函数可能抛出的异常有哪些。 可以在函数的后面接throw(类型),列出这个函数可能抛掷的所有异常类型。
  2. 函数的后面接throw(),表示函数不抛异常。
  3. 若无异常接口声明,则此函数可以抛掷任何类型的异常。
// 这里表示这个函数会抛出A/B/C/D中的某种类型的异常
void fun() throw(A,B,C,D);
// 这里表示这个函数只会抛出bad_alloc的异常
void* operator new (std::size_t size) throw (std::bad_alloc);
// 这里表示这个函数不会抛出异常
void* operator delete (std::size_t size, void* ptr) throw();

// C++11 中新增的noexcept,表示不会抛异常
thread() noexcept;
thread (thread&& x) noexcept;

C++标准库的异常体系

在这里插入图片描述

在这里插入图片描述

异常的优缺点

优点:

  1. 异常对象定义好了,相比错误码的方式可以清晰准确的展示出错误的各种信息,甚至可以包含堆栈调用的信息,这样可以帮助更好的定位程序的bug。
  2. 返回错误码的传统方式有个很大的问题就是,在函数调用链中,深层的函数返回了错误,那么我们得层层返回错误,最外层才能拿到错误。异常可以直接返回到最外层。
  3. 很多的第三方库都包含异常,比如boost、gtest、gmock等等常用的库,那么我们使用它们也需要使用异常。
  4. 部分函数使用异常更好处理,比如构造函数没有返回值,不方便使用错误码方式处理。比如T& operator这样的函数,如果pos越界了只能使用异常或者终止程序处理,没办法通过返回值表示错误。

缺点:

  1. 异常会导致程序的执行流乱跳,并且非常的混乱,并且是运行时出错抛异常就会乱跳。这会导致我们跟踪调试时以及分析程序时,比较困难。
  2. 异常会有一些性能的开销。当然在现代硬件速度很快的情况下,这个影响基本忽略不计。
  3. C++没有垃圾回收机制,资源需要自己管理。有了异常非常容易导致内存泄漏、死锁等异常 安全问题。这个需要使用RAII来处理资源的管理问题。学习成本较高。
  4. C++标准库的异常体系定义得不好,导致大家各自定义各自的异常体系,非常的混乱。
  5. 异常尽量规范使用,否则后果不堪设想,随意抛异常,外层捕获的用户苦不堪言。所以异常 规范有两点:一、抛出异常类型都继承自一个基类。二、函数是否抛异常、抛什么异常,都 使用 func() throw();的方式规范化。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++异常 的相关文章

  • 如何在 C# Designer.cs 代码中使用常量字符串?

    如何在 designer cs 文件中引用常量字符串 一个直接的答案是在我的 cs 文件中创建一个私有字符串变量 然后编辑 Designer cs 文件以使用此变量 而不是对字符串进行硬编码 但设计者不喜欢这样抛出错误 我明白为什么这行不通
  • 如何使用 Java 在 selenium webdriver 中打开新选项卡或如何使用使用 selenium webdriver 的操作类在 selenium 中按 ctrl +T [重复]

    这个问题在这里已经有答案了 如何使用 Java 在 Selenium Webdriver 中按 CTRL T 或者 如何使用 Java 在 selenium webdriver 中打开新选项卡 简单步骤 1 打开google com 不必触
  • JPA Web 应用程序管理策略

    我们目前正在开发一个 J2EE Web 应用程序 使用 JPA 作为我们的数据访问层 我们目前正在研究几种不同的策略来在我们的应用程序中利用缓存 Create an EntityManager per request 在请求范围内获取缓存
  • Janusgraph 0.3.2 + HBase 1.4.9 - 无法设置 graph.timestamps

    我在 Docker 容器中运行 Janusgraph 0 3 2 并尝试使用运行 HBase 1 4 9 的 AWS EMR 集群作为存储后端 我可以运行 gremlin server sh 但如果我尝试保存某些内容 我会得到粘贴在下面的堆
  • Hibernate 标准接受 %% 值

    我正在使用下面的 Hibernate 代码来过滤workFlowName crt add Restrictions like workFlowName workFlow MatchMode ANYWHERE crt is the crite
  • 在 VS 中运行时如何查看 C# 控制台程序的输出?

    我刚刚编写了一个名为 helloworld 的聪明程序 它是一个 C NET 4 5 控制台应用程序 在扭曲的嵌套逻辑迷宫深处 使用了 Console WriteLine 当我在命令行运行它时 它会运行并且我会看到输出 我可以执行其他命令并
  • 是否使用 C# 数据集? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我对 C 中的数据集概念有点困惑 编码 ASP NET 站点 但这并不重要 在我的阅读中 我了解到它们 本质上 用作我的应用程序和我的
  • 无法连接到docker中的elasticsearch容器

    我正在尝试使用 docker 的官方 elasticsearch 镜像 我遵循了本指南 https www elastic co guide en elasticsearch reference current docker html但是当
  • 从网页运行 ClickOnce 应用程序,无需用户操作

    我们有一个基于 Java 的 Web 应用程序以及用 C 编写的相同应用程序 如果 java 检查器发现客户端计算机上没有安装 Java 则应该运行该应用程序 这个想法是运行 C 单击一次 http en wikipedia org wik
  • 在 .NET MAUI 中实现 TouchTracking

    我一直致力于将我们的应用程序从 Xamarin Forms 迁移到 NET MAUI 我们的应用程序几乎没有绘图功能 用户可以用手指进行绘图 我们用了TouchTrackingXamarin Forms 中的 nuget 包 但与 NET
  • 从 C# 使用 Odbc 调用 Oracle 包函数

    我在 Oracle 包中定义了一个函数 CREATE OR REPLACE PACKAGE BODY TESTUSER TESTPKG as FUNCTION testfunc n IN NUMBER RETURN NUMBER as be
  • 如果输入被重定向则执行操作

    我想知道如果我的输入被重定向 我应该如何在 C 程序中执行操作 例如 假设我有已编译的程序 prog 并且我将输入 input txt 重定向到它 我这样做 prog lt input txt 我如何在代码中检测到这一点 一般来说 您无法判
  • 在 C 中使用枚举而不是 #defines 作为编译时常量是否合理?

    在 C 工作了一段时间后 我将回到 C 开发领域 我已经意识到 在不必要的时候应该避免使用宏 以便让编译器在编译时为您做更多的工作 因此 对于常量值 在 C 中我将使用静态 const 变量或 C 11 枚举类来实现良好的作用域 在 C 中
  • 为什么不能在 if 语句中声明变量?

    以下 Java 代码无法编译 int a 0 if a 1 int b 0 if a 1 b 1 为什么 不能有任何代码路径导致程序将 1 分配给b无需先声明 我突然想到b的变量范围可能仅限于第一个if声明 但后来我不明白为什么 如果我实在
  • 在java中执行匿名pl/sql块并获取结果集

    我想执行匿名 PL SQL 并需要获取结果集对象 我得到了可以通过在 PL SQL 块内使用游标来完成的代码 但 PL SQL 块本身将以文本形式来自数据库 所以我无法编辑该 PL SQL 块 并且它只会返回两个值 其列名始终相同 它将返回
  • Firebase:用户注册后如何进行电话号码验证?

    所以我知道我可以使用电子邮件验证或电话号码验证 但我想做的是在用户注册或登录后进行电话号码验证 如何连接这两种身份验证方法 最后 Firebase中是否有一个函数可以检查用户是否通过电话号码验证 谢谢 即使用户已通过身份验证 您仍然可以使用
  • WPF DataGrid / ListView 绑定到数组 mvvm

    我们假设你有 N 个整数的数组 表示行数的整数值 在模型中 该整数绑定到视图中的 ComboBox Q1 如何将数组 或数组的各个项目 绑定到 DataGrid 或 ListView 控件 以便 当您更改 ComboBox 值时 只有那么多
  • Java 中序列化的目的是什么?

    我读过很多关于序列化的文章 以及它如何如此美好和伟大 但没有一个论点足够令人信服 我想知道是否有人能真正告诉我通过序列化一个类我们真正可以实现什么 让我们先定义序列化 然后我们才能讨论它为什么如此有用 序列化只是将现有对象转换为字节数组 该
  • EntityFramework 6.0.0.0 读取数据,但不插入

    我创建了一个基于服务的数据库 folderName gt Add New Item gt Data gt Service based Database文件到 WPF 应用程序中 然后我用过Database First方法并创建了Person
  • 在 System.Type 上使用条件断点时出错

    这是函数 public void Init System Type Type this Type Type BuildFieldAttributes BuildDataColumns FieldAttributes 我在第一行设置了一个断点

随机推荐

  • 【csv】csv文件存储上数据精度丢失问题

    最近发现较长的id信息在csv文件中会发生精度丢失 当然python直接处理数据是没问题的 只是csv显示有问题 case1 通常在Excel中输入数值时 如果超过11位 12位及以上 Excel就会用科学计数法显示该数值 如 123456
  • 让macOS支持读写NTFS格式的移动硬盘

    第一步 获知磁盘的名称 两种方法可以知道磁盘名称 第一种 当插入移动硬盘时 桌面上会出现移动硬盘的图标还有名称 第二种 打开终端 输入diskutil list 即可知道磁盘名称 由图中可知我的移动硬盘名称是 备份 第二步 打开终端 按照以
  • 操作系统的逻辑结构

    2 1 操作系统的逻辑结构 逻辑结构 OS的设计和实现思路 逻辑结构的种类 1 整体结构 2 层次式结构 3 微内核结构 客户 服务器结构 Client Server 操作系统作为一个大型软件 它的设计逻辑实现的思路 我们叫做操作系统的逻辑
  • 壁纸网站研究:强大到没朋友的壁纸网站整理(动漫/二次元/宅男/风景/真人)

    1 wallhaven 域名 https wallhaven cc 介绍 一个强大的壁纸网站 包含人物 动漫 风景 同时有一些老司机内容 需要选择NSFW 但需要登录才能观看 隐藏功能 但是海外网站 国内网站较慢 有时候打不开 总结 语言
  • 【华为OD机试真题2023B卷 JAVA&JS】内存资源分配

    华为OD2023 B卷 机试题库全覆盖 刷题指南点这里 内存资源分配 知识点贪心编程基础 时间限制 1s 空间限制 32MB 限定语言 不限 题目描述 有一个简易内存池 内存按照大小粒度分类 每个粒度有若干个可用内存资源 用户会进行一系列内
  • Spring 中容器启动分析之refresh方法执行之前

    内容来自 自学星球 欢迎大家来了解我的星球 和星主 也就是我 一起学习 Java 深入 Java 体系中的所有技术 我给自己定的时间是一年 无论结果如何 必定能给星球中的各位带来点东西 想要了解更多 欢迎访问 自学星球 SSM系列源码文章及
  • JavaScript随机生成颜色

    function getRandomColor const letters 0123456789ABCDEF let color for let i 0 i lt 6 i color letters Math floor Math rand
  • IPv4数据报的分段与重组

    文章摘自书籍 深入理解计算机网络 王达 机械工业出版社 IPv4数据报头格式请点击此处 IPv4数据报的封装与解封装请点击此处 IPv4数据报的分段与重组 在网络层中还涉及一个分段的问题 那就是因为不同网络线路上可以传输的数据报大小是有限制
  • QT学习记录(三)通过ui和代码的方式往窗口添加组件

    写在前面 本文是b站教程的https www bilibili com video BV1g4411H78N p 5 vd source a3efe214b8a2ba185e92e79cb6d6321b的笔记 外加自己的一些其他想法 如有侵
  • mnist example for lstm in caffe

    下面给出在caffe中使用lstm的一个例子 其中数据集采用mnist 为了实现mnist数据的序列话 将mnist的每一行看成一帧 每一列则就是该帧的特征矢量 在使用lstm时 一定要注意clip markers 每个序列以0开始 后面接
  • Unity 编辑器-创建模板脚本,并自动绑定属性,添加点击事件

    当使用框架开发时 Prefab挂载的很多脚本都有固定的格式 从Unity的基础模板创建cs文件 再修改到应有的模板 会浪费一些时间 尤其是有大量的不同界面时 每个都改一遍 浪费时间不说 还有可能遗漏或错改 写个脚本创建指定的模板代替C 基础
  • 基于Spark的电商用户行为实时分析可视化系统(Flask-SocketIO)

    基于Spark的电商用户行为实时分析可视化系统 Flask SocketIO 项目简介 该项目已上线蓝桥课程 有需要的可凭邀请码 UB5mdLbl 学习哦 有优惠 课程地址 https www lanqiao cn courses 2629
  • 拉普拉斯时域卷积定理_如何证明频域卷积定理

    展开全部 设抄 IF表示傅立叶逆变换 则 因此有袭 故频域卷积定2113理5261得证 4102 扩展资料 频域卷积定理 频域卷积定理表明两信号1653在时域的乘积对应于这两个信号傅立叶变换的卷积除以2 卷积定理揭示了时间域与频率域的对应关
  • nacos注册中心/配置中心的使用

    Nacos下载 https github com alibaba nacos releases Nacos启动 此处为了演示方便 下载的是 Windows版本 nacos server 2 2 2 zip 进入 nacos server 2
  • response.setCharacterEncoding(charset) 报错

    eclipse tomcat服务启动运行项目 代码 response setCharacterEncoding charset 标红 我自己百度了很多 有一个说法是最靠谱的 HttpServletResponse存在于servlet api
  • JQ了解

    jQuery 一 jQuery的了解 1 定义 jQuery是一个兼容多浏览器的JavaScript框架 可以使用户方便地处理HTML 事件 实现动画效果 并且为网站提供方便的Ajax交互 2 作用 JS操作DOM的一个库 特点 轻量级 出
  • Maven构建与管理项目(二)

    Maven构建与管理项目 二 Maven核心概念 Maven坐标 什么是坐标 在平面几何中坐标 x y 可以标识平面中唯一的一点 Maven坐标主要组成 groupId 组织标识 包名 artifactId 项目名称 version 项目的
  • ST外设使用出错,一般排查步骤

    FMC 通信有误排查过程 1 STM32 官方设计资源 https www stmcu com cn STM32中文官网 gt 设计资源 gt 实战经验 2 Cube 库当中的官方例程 使用 everything 搜索 FMC 关键词 从而
  • 新路子!chatGPT+Python爬虫接私单怎么玩?

    就在这两天 关于ChatGPT的疾呼突然在社交平台上刷屏 很多人发现自己的号已经不在了 用户们感到前所未有的惶恐 已经有不少公司把 chatGPT引入工作流 未来已来 AI智能时代真的来了 普通人如何在智能时代谋求发展 这里提供一个思路 c
  • C++异常

    全文目录 概念 异常的抛出 在函数调用链中异常栈展开匹配原则 异常的重新抛出 异常安全 异常规范 C 标准库的异常体系 异常的优缺点 概念 C语言处理异常的方式 终止程序 返回错误码 很多系统的库函数就是使用这中方式 C 异常 异常是一种处