C++异常处理时的异常类型抛出选择
在 C++ 中选择抛出哪种异常类型,主要取决于错误的性质以及希望传达的语义信息。以下是一些指导原则,帮助在可能发生异常的地方选择合适的异常类型进行抛出:
1. std::exception
- 适用场景:作为所有标准异常的基类,
std::exception本身通常不直接用于抛出异常,而是作为自定义异常类的基类。 - 使用场景:如果需要定义自己的异常类,可以继承
std::exception。
2. std::runtime_error
- 适用场景:用于报告运行时错误,即在程序运行过程中由于外部条件或不可预见的情况导致的错误。
- 常见情况:
- 文件操作失败(如文件无法打开)。
- 网络连接失败。
- 动态加载库失败。
- 其他与运行环境相关的错误。
3. std::logic_error
- 适用场景:用于报告逻辑错误,即程序内部的逻辑问题,通常是由于程序设计不当或输入不符合预期导致的错误。
- 常见情况:
- 参数验证失败(如函数参数不符合要求)。
- 无效的状态转换。
- 未实现的功能被调用。
- 其他由于程序逻辑错误导致的问题。
4. std::out_of_range
- 适用场景:用于报告越界错误,即访问了超出有效范围的索引或位置。
- 常见情况:
- 访问容器(如
std::vector、std::string)时索引超出范围。 - 访问数组时索引越界。
- 访问容器(如
5. std::bad_alloc
- 适用场景:用于报告内存分配失败的错误。
- 常见情况:
new操作符无法分配内存时,会抛出std::bad_alloc。- 其他内存分配相关的失败情况。
具体选择的依据
-
错误的性质:
- 如果错误是由于运行时外部条件导致的,选择
std::runtime_error。 - 如果错误是由于程序逻辑问题导致的,选择
std::logic_error。 - 如果错误是由于越界访问导致的,选择
std::out_of_range。 - 如果错误是由于内存分配失败导致的,选择
std::bad_alloc。
- 如果错误是由于运行时外部条件导致的,选择
-
语义清晰性:
- 选择能够最好地描述错误类型的异常类,这样可以让捕获异常的代码更容易理解错误的来源和性质。
-
代码风格和团队约定:
- 在团队开发中,遵循团队的编码规范和异常处理约定,保持一致性。
示例代码
#include <iostream>
#include <stdexcept>
#include <vector>void processFile(const std::string& filename) {// 模拟文件打开失败的运行时错误if (filename.empty()) {throw std::runtime_error("Filename is empty");}
}void validateInput(int value) {// 模拟逻辑错误,参数不符合要求if (value < 0) {throw std::logic_error("Input value cannot be negative");}
}int getElement(std::vector<int>& vec, size_t index) {// 模拟越界错误if (index >= vec.size()) {throw std::out_of_range("Index out of range");}return vec[index];
}int main() {try {processFile(""); // 可能抛出 std::runtime_error} catch (const std::runtime_error& e) {std::cout << "Runtime error: " << e.what() << std::endl;}try {validateInput(-5); // 可能抛出 std::logic_error} catch (const std::logic_error& e) {std::cout << "Logic error: " << e.what() << std::endl;}try {std::vector<int> vec = {1, 2, 3};getElement(vec, 5); // 可能抛出 std::out_of_range} catch (const std::out_of_range& e) {std::cout << "Out of range error: " << e.what() << std::endl;}return 0;
}
选择抛出哪种异常类型,主要依据错误的性质和希望传达的语义信息。std::runtime_error 用于运行时错误,std::logic_error 用于逻辑错误,std::out_of_range 用于越界错误,std::bad_alloc 用于内存分配错误。通过合理选择异常类型,可以使代码更具可读性和可维护性。
在C++中,选择抛出哪种标准异常类需要根据错误的类型、发生场景以及标准库的规范来判断。具体的选择依据和常见场景如下:
一、标准异常类的分类与适用场景
std::exception- 基类:所有标准异常的基类,通常不直接抛出,而是通过其派生类使用。
- 适用场景:当需要统一捕获所有异常时,例如:
catch (const std::exception& e) {std::cerr << e.what(); // 输出错误信息 }
std::runtime_error- 运行时错误:表示无法在编译时检测到的错误,例如内存分配失败、系统资源不足等。
- 典型用例:
- 内存分配失败时抛出
std::bad_alloc(runtime_error的子类)。 - 文件操作失败(如打开不存在的文件)。
- 内存分配失败时抛出
std::logic_error- 逻辑错误:表示可以通过代码逻辑避免的错误,例如参数校验失败、算法逻辑错误等。
- 常见子类:
std::invalid_argument:参数无效(如除零操作)。std::out_of_range:索引越界(如访问容器超出范围的元素)。std::domain_error:数学运算中使用无效的输入域(如对负数开平方根)。
- 其他具体异常类
std::bad_cast:dynamic_cast类型转换失败时抛出。std::bad_typeid:typeid操作符作用于NULL指针时抛出。
二、选择异常类的判断依据
- 错误类型是否可预见
- 逻辑错误(
logic_error):若错误可通过代码逻辑提前检测(如参数校验),应抛出逻辑错误类。 - 运行时错误(
runtime_error):若错误无法在编译时或运行时早期检测(如内存分配失败),应抛出运行时错误类。
- 逻辑错误(
- 错误的粒度
- 优先使用具体子类:例如,参数无效时应抛出
std::invalid_argument,而非更宽泛的std::runtime_error。 - 自定义异常类:若标准类无法准确描述错误,可继承
std::exception自定义异常类。
- 优先使用具体子类:例如,参数无效时应抛出
- 标准库的约定
- 遵循标准库的异常抛出规则。例如:
std::vector::at()在越界时抛出std::out_of_range。new操作符在内存不足时抛出std::bad_alloc。
- 遵循标准库的异常抛出规则。例如:
三、示例代码
- 参数校验失败(逻辑错误)
void divide(int a, int b) {if (b == 0) {throw std::invalid_argument("Divisor cannot be zero");} } - 内存分配失败(运行时错误)
int* createArray(size_t size) {try {return new int[size];} catch (const std::bad_alloc& e) {std::cerr << "Memory allocation failed: " << e.what();return nullptr;} } - 索引越界(逻辑错误)
std::vector vec = {1, 2, 3}; try {int value = vec.at(5); // 抛出 std::out_of_range } catch (const std::out_of_range& e) {std::cerr << "Index out of range: " << e.what(); }
四、最佳实践
- 优先使用标准异常类:避免重复造轮子,提高代码可读性和可维护性。
- 明确异常边界:在函数文档中注明可能抛出的异常类型。
- 避免过度捕获:尽量捕获具体异常类型,而非笼统的
catch (...),以提高错误处理的精确性。
通过以上规则和示例,可以更合理地选择抛出异常的类型,使代码更加健壮和易维护。
相关文章:
C++异常处理时的异常类型抛出选择
在 C 中选择抛出哪种异常类型,主要取决于错误的性质以及希望传达的语义信息。以下是一些指导原则,帮助在可能发生异常的地方选择合适的异常类型进行抛出: 1. std::exception 适用场景:作为所有标准异常的基类,std::e…...
elsticsearch 通过reindex修改shards
elasticsearch reindex 索引。 背景: 索引test1 reindex到test2 修改sharding数量 程序是通过别名test1_alias访问索引 1、创建目标索引test2 索引需要手动提前创建自动创建可能会有mapping 不一致性的风险。 The destination should be configured as wanted …...
CentOS系类普通挂载磁盘挂载命令
检查磁盘是否有分区 lsblk如果 vdb 下面没有分区(比如 vdb1),你需要先创建分区。 创建分区(如果需要) fdisk /dev/vdb然后在 fdisk 交互界面: 输入 n 创建新分区 选择 p 创建主分区 默认分区号和大小 输…...
Kafka自定义分区机制
文章目录 1.如何自定义分区机制2.示例 1.如何自定义分区机制 若需要使用自定义分区机制,需要完成两件事: 1)在 producer 程序中创建一个类,实现 org.apache.kafka.clients.producer.Partitioner 接口主要分区逻辑在 Partitioner.partition中…...
【HarmonyOS NEXT】关键资产存储开发案例
在 iOS 开发中 Keychain 是一个非常安全的存储系统,用于保存敏感信息,如密码、证书、密钥等。与文件系统不同,Keychain 提供了更高的安全性,因为它对数据进行了加密,并且只有经过授权的应用程序才能访问存储的数据。那…...
强化学习(赵世钰版)-学习笔记(9.策略梯度法)
本章是课程的导数第二章,旨在讲解策略的函数化形式。 之前的方法,描述一个策略都是用表格的形式,每一行代表一个状态,每一列代表一个行为,表格中的元素对应相关状态下执行相关行为的概率。 函数化的策略表征形式是指&a…...
ModuleNotFoundError: No module named ‘flask‘ 错误
要解决 ModuleNotFoundError: No module named ‘flask’ 错误,需确保已正确安装 Flask 库。以下是详细步骤: 1. 安装 Flask 在终端或命令行中执行以下命令(注意权限问题): 使用 pip 安装 pip install flask 若…...
【c++】【STL】unordered_set 底层实现(简略版)
【c】【STL】unordered_set 底层实现(简略版) ps:这个是我自己看的不保证正确,觉得太长的后面会总结整个调用逻辑 unordered_set 内部实现 template <class _Kty, class _Hasher hash<_Kty>, class _Keyeq equal_to<_Kty>…...
【Zephyr】【一】学习笔记
Zephyr RTOS 示例代码集 1. 基础示例 1.0 基础配置 每个示例都需要一个 prj.conf 文件来配置项目。以下是各个示例所需的配置: 基础示例 prj.conf # 控制台输出 CONFIG_PRINTKy CONFIG_SERIALy CONFIG_UART_CONSOLEy# 日志系统 CONFIG_LOGy CONFIG_LOG_DEFAULT…...
网络安全设备配置与管理-实验4-防火墙AAA服务配置
实验4-p118防火墙AAA服务配置 从这个实验开始,每一个实验都是长篇大论😓 不过有好兄弟会替我出手 注意:1. gns3.exe必须以管理员身份打开,否则ping不通虚拟机。 win10虚拟机无法做本次实验,必须用学校给的虚拟机。首…...
后端框架模块化
后端框架的模块化设计旨在简化开发流程、提高可维护性,并通过分层解耦降低复杂性。以下是常见的后端模块及其在不同语言(Node.js、Java、Python)中的实现方式: 目录 1. 路由(Routing)2. 中间件(…...
【论文阅读】Contrastive Clustering Learning for Multi-Behavior Recommendation
论文地址:Contrastive Clustering Learning for Multi-Behavior Recommendation | ACM Transactions on Information Systems 摘要 近年来,多行为推荐模型取得了显著成功。然而,许多模型未充分考虑不同行为之间的共性与差异性,以…...
视频转音频, 音频转文字
Ubuntu 24 环境准备 # 系统级依赖 sudo apt update && sudo apt install -y ffmpeg python3-venv git build-essential python3-dev# Python虚拟环境 python3 -m venv ~/ai_summary source ~/ai_summary/bin/activate核心工具链 工具用途安装命令Whisper语音识别pip …...
基于协同过滤推荐算法的景点票务数据系统(python-计算机毕设)
摘 要 I ABSTRACT II 第 1 章 引言 1 研究背景及意义 1 研究背景 1研究意义 1 国内外研究现状 2 智慧旅游 3旅游大数据 3 研究内容 4本章小结 4 第 2 章 相关技术概述 5 基于内容的推荐算法 5 基于内容的推荐算法原理 5基于内容的推荐算法实现 5 协同过滤推荐算法 6 协同过…...
QT学习笔记1
** Qt Creator开发环境配置** 安装流程(Windows平台) 下载与安装 : 访问Qt官网,下载在线安装工具Qt Online Installer。登录或注册Qt账号,选择开源版本(需勾选“接受协议”)。勾选组件ÿ…...
Ubuntu 24 常用命令方法
文章目录 环境说明1、账号管理1.1、启用 root 2、包管理工具 apt & dpkg2.1、apt 简介 & 阿里源配置2.2、dpkg 简介2.3、apt 和 dpkg 两者之间的关系2.4、常用命令 3、启用 ssh 服务4、防火墙5、开启远程登录6、关闭交换分区7、build-essential(编译和开发软…...
Flask多参数模版使用
需要建立目录templates; 把建好的html文件放到templates目录里面; 约定好参数名字,单个名字可以直接使用;多参数使用字典传递; 样例: from flask import render_template # 模板 (Templates) #Flask 使用…...
torcharrow gflags版本问题
问题描述 其实仍然是很简单的编译问题,但是又弄了一整个下午加几乎整个晚上,进度缓慢,又吸取了教训,因而还是来记录一下。 在试图使用torcharrow进行推荐系统模拟的时候,撰写的python程序报错:ERROR: flag…...
自然语言处理|深入解析 PEGASUS:从原理到实践
一、引言 在信息爆炸的时代,互联网上的文本数据以极快的速度增长。无论是新闻资讯、学术论文、社交媒体动态,还是各类报告文档,我们每天接触到的文字信息量巨大。如何快速、准确地提取关键内容成为一项重要任务。文本摘要技术通过将长篇文本…...
Spring AI Alibaba快速使用
AI 时代,Java 程序员也需要与时俱进,这两个框架必须掌握。 一个是 Spring AI一个是 Spring Alibaba AI。 Spring AI 是一个AI工程领域的应用程序框架,它的目标是将 Spring生态系统的设计原则应用于人工智能领域。 但是, Spring…...
socks 协议介绍
SOCKS协议详解 一、基本定义与核心功能 SOCKS(Socket Secure)是一种网络传输协议,主要用于通过代理服务器转发客户端与目标服务器之间的通信请求。其核心功能包括隐藏用户真实IP地址、穿透防火墙限制以及支持多种网络协议(如TCP…...
Linux --centos安装显卡驱动
显卡下载页面 https://www.nvidia.com/en-us/drivers/unix/ 随便下载一个即可 安装过程 查看当前设备的显卡信息 lspci | grep -i vga安装gcc相关依赖 yum update -y yum update gcc yum install build-essential yum install gcc-multilibdkms yum groupinstall "Dev…...
【软件工程】简答题
真题 2024-10 26.需求验证应验证需求规格说明书中每一单一需求是否满足5个性质,这5个性质是什么? 27.简述RUP和UML的关系。 28.简述五种常见的模块间耦合类型。 29.螺旋模型在笛卡尔坐标的4个象限上,分别表达了哪4个方面的活动? 30.为了表达概念模型和软件模型,UML提供了13…...
统信UOS中使用Vscode编程
写在前面:统信UOS其实就是套壳的Linux系统,所以有问题如果搜不到解决方法,可以参考Linux下的解决方法。 1.环境配置 Vscode : 1.85.0 Vscode就直接下载安装就行,然后安装插件:Volar、中文汉化包 node:18…...
K8s认证(CKA/CKAD/CKS)哪家强?主流证书对比
2024年Kubernetes认证全解析:选对证书,薪资翻倍! (附CKA/CKAD/CKS最新考试攻略) 一、K8s认证哪家强?主流证书对比 认证名称颁发机构考试特点适合人群考试费用CKA(认证K8s管理员)CN…...
HTTP1.0、HTTP1.1、HTTP2.0对比
HTTP 1.0、HTTP 1.1 和 HTTP 2.0 是 HTTP 协议演进中的三个重要版本,每个版本都针对前一代的不足进行了优化和改进。以下是它们的核心区别和关键特性对比: 1. HTTP 1.0(1996年) 非持久连接 每个请求/响应对都需要单独建立和关闭 T…...
docker安装向量数据库Milvus及可视化工具 Attu
前置条件 1.安装了docker 2.服务器网络正常,可以连接到容器下载地址 3.服务器磁盘空间正常,docker磁盘占用过大,请参考docker容量占用过大解决办法 一、下载yml文件 可在文章资源下载或者自行下载:下载yml 下载这个单机版本的…...
A l密码学(Deepseek)
我:qwertyuiopasdfghjklzxcvbnm deepseek:深度思考中. Okay, lets see. The user input is "qwertyuiopasdfghjklzxcvbnm". At first glance, it looks like a jumbled sequence of letters with some spaces or maybe other characters in …...
DeepSeek + Kimi 自动生成 PPT
可以先用deepseek生成ppt大纲,再把这个大纲复制到Kimi的ppt助手里: https://kimi.moonshot.cn/kimiplus/conpg18t7lagbbsfqksg 选择ppt模板: 点击生成ppt就制作好了。...
Apache Paimon 在抖音集团多场景中的优化实践
资料来源:火山引擎-开发者社区 本文将基于抖音集团内部两大业务的典型实时数仓场景,介绍Paimon在抖音集团内部的生产实践。 作者:李明、苏兴、文杰 抖音集团大数据工程师 目前抖音集团内部主要使用 Lambda 架构进行实时数仓建设,其…...
