C++学习路程-8-C++错误处理

C++中的错误处理是一个重要的主题,它涉及如何检测和处理程序中的异常情况,以确保程序的健壮性和稳定性。C++提供了多种错误处理机制,其中最主要的是异常处理机制。下面将详细介绍C++中的错误处理相关知识,包括异常的概念、使用方法、标准异常类、自定义异常以及常见的错误处理策略等。

1. 错误处理的概念

错误处理是指在程序运行过程中对错误或异常情况的检测和处理。错误可能来源于多种因素,例如:

  • 用户输入错误(如非法字符)
  • 文件无法打开(如文件不存在)
  • 内存分配失败(如内存不足)
  • 逻辑错误(如数组越界)

有效的错误处理可以提高程序的可靠性,使程序能够优雅地应对意外情况。

2. 异常处理机制

2.1 异常的基本概念

异常是程序执行过程中发生的意外事件,通常表示错误或不寻常的情况。C++使用异常处理机制来对这些情况进行处理,允许程序员在出现错误时采取适当的措施。

2.2 异常的语法

C++中的异常处理使用三个关键字:

  • try:用于定义可能引发异常的代码块。
  • throw:用于抛出异常。
  • catch:用于捕获和处理异常。

2.3 基本的异常处理示例

cpp

#include <iostream>
#include <stdexcept> // 包含标准异常类int divide(int a, int b) {if (b == 0) {throw std::invalid_argument("Division by zero!"); // 抛出无效参数异常}return a / b;
}int main() {try {std::cout << divide(10, 2) << std::endl; // 正常情况std::cout << divide(10, 0) << std::endl; // 引发异常} catch (const std::invalid_argument& e) { // 捕获特定异常std::cerr << "Error: " << e.what() << std::endl; // 输出异常信息}return 0;
}

3. 标准异常类

C++标准库提供了一组标准异常类,位于<stdexcept>头文件中。这些异常类用于表示不同类型的错误。

3.1 常用标准异常类

  • std::exception:所有标准异常的基类。
  • std::runtime_error:表示运行时错误,通常表示程序在运行期间遇到的问题。
  • std::invalid_argument:表示无效参数错误,通常用于函数参数不符合要求的情况。
  • std::out_of_range:表示超出范围的错误,通常用于访问容器元素时,索引超出范围。
  • std::logic_error:表示逻辑错误,通常用于由于程序逻辑错误导致的异常情况。

3.2 使用标准异常的示例

cpp

#include <iostream>
#include <stdexcept>void checkValue(int value) {if (value < 0) {throw std::invalid_argument("Value must be non-negative!"); // 抛出无效参数异常}
}int main() {try {checkValue(-1); // 引发异常} catch (const std::invalid_argument& e) {std::cerr << "Caught an exception: " << e.what() << std::endl; // 输出异常信息}return 0;
}

4. 自定义异常

在某些情况下,内置的异常类可能无法满足需求,此时可以定义自定义异常类。

4.1 创建自定义异常类

自定义异常类通常需要继承自std::exception并重写what()方法,以提供错误信息。

示例:自定义异常类

cpp

#include <iostream>
#include <exception>
#include <string>class MyException : public std::exception {
public:MyException(const std::string& message) : msg(message) {}virtual const char* what() const noexcept override { // 重写what方法return msg.c_str(); // 返回错误信息}private:std::string msg; // 存储错误信息
};void riskyFunction() {throw MyException("Something went wrong in riskyFunction!"); // 抛出自定义异常
}int main() {try {riskyFunction(); // 调用可能引发异常的函数} catch (const MyException& e) {std::cerr << "Caught a custom exception: " << e.what() << std::endl; // 捕获并输出自定义异常信息}return 0;
}

5. 异常处理的策略

5.1 预防性编程

通过代码审查、单元测试和良好的编程习惯,尽量在编写代码时预防错误的发生。例如,使用条件语句检查输入有效性。

5.2 使用异常处理

通过异常处理机制捕获和处理错误,确保程序在异常情况下能继续运行或优雅退出。

5.3 日志记录

记录错误和异常信息,以便后续分析和调试。可以使用日志库记录详细的错误信息,包括异常发生的时间、位置和错误原因。

5.4 清理资源

catch块中,确保释放动态分配的内存或关闭打开的文件,防止资源泄漏。这通常可以通过RAII(资源获取即初始化)技术实现。

示例:资源管理

cpp

#include <iostream>
#include <fstream>void manageResource() {std::ifstream file("nonexistent.txt"); // 尝试打开一个不存在的文件if (!file.is_open()) {throw std::runtime_error("Failed to open the file!"); // 抛出运行时错误}// 其他操作...
}int main() {try {manageResource(); // 调用可能引发异常的函数} catch (const std::runtime_error& e) {std::cerr << "Caught an exception: " << e.what() << std::endl; // 捕获并输出异常信息}return 0;
}

6. 异常安全

6.1 异常安全的定义

异常安全是指在抛出异常时,程序能够保持一致的状态,避免资源泄漏和数据损坏。

6.2 异常安全的保证

  • 基本保证:在异常发生时,程序的状态是有效的。
  • 强保证:在异常发生时,操作要么完成,要么不对状态产生影响。
  • 无异常保证:保证在特定的操作中,不会抛出异常。

示例:异常安全的实现

cpp

#include <iostream>
#include <vector>
#include <stdexcept>class SafeVector {
public:void add(int value) {data.push_back(value); // 添加元素}int get(size_t index) const {if (index >= data.size()) {throw std::out_of_range("Index out of range!"); // 抛出超出范围异常}return data[index]; // 返回元素}private:std::vector<int> data; // 存储整数的动态数组
};int main() {SafeVector vec;try {vec.add(1);vec.add(2);std::cout << vec.get(2) << std::endl; // 引发异常} catch (const std::out_of_range& e) {std::cerr << "Error: " << e.what() << std::endl; // 捕获并输出异常信息}return 0;
}

7. 其他错误处理方式

除了异常处理,C++还可以通过其他方式处理错误:

7.1 代码返回值

通过函数返回值来指示是否发生错误。这种方法简单,但不够优雅,且容易被忽略。

cpp

bool divide(int a, int b, int& result) {if (b == 0) {return false; // 返回false表示发生错误}result = a / b; // 计算结果return true; // 返回true表示成功
}

7.2 全局错误处理

通过全局变量或状态来跟踪错误。这种方法不推荐,因为它可能导致代码难以维护。

总结

C++中的错误处理机制为开发者提供了一种结构化的方法来处理程序中的异常和错误。通过合理使用异常处理机制、标准异常类、自定义异常和良好的错误处理策略,可以提高程序的可靠性和可维护性。在实际开发中,建议结合使用预防性编程、日志记录和异常安全策略,以确保程序在各种情况下的稳定性。

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

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

相关文章

【论文阅读笔记】Learning to sample

Learning to sample 前沿引言方法问题声明S-NET匹配ProgressiveNet: sampling as ordering 实验分类检索重建 结论附录 前沿 这是一篇比较经典的基于深度学习的点云下采样方法 核心创新点&#xff1a; 首次提出了一种学习驱动的、任务特定的点云采样方法引入了两种采样网络&…

Mysql大数据量表分页查询性能优化

一、模拟场景 1、产品表t_product,数据量500万+ 2、未做任何优化前,cout查询时间大约4秒;LIMIT offset, count 时,offset 值较大时查询时间越久。 count查询 SELECT COUNT(*) AS total FROM t_product WHERE deleted = 0 AND tenant_id = 1 分页查询 SELECT * FROM t_…

pythonWeb~伍~初识Django

初识Django 1.技术栈 Python知识点&#xff1a;函数、面向对象。前端知识点&#xff1a;HTML、CSS、JavaScript、jQuery、BootStrap。MySQL数据库。Python的Web框架&#xff1a; Flask&#xff0c;自身短小精悍 第三方组件。Django&#xff0c;内部已集成了很多组件 第三方…

kimi搜索AI多线程批量生成txt原创文章软件-不需要账号及key

kimi搜索AI多线程批量生成txt原创文章软件介绍&#xff1a; 软件可以设置三种模型写文章&#xff1a;kimi&#xff1a;默认AI模型&#xff0c;kimi-search&#xff1a;联网检索模型 &#xff0c;kimi-research&#xff1a;探索版搜索聚合模型 1、可以设置写联网搜索文章&#…

DevNow x Notion

前言 Notion 应该是目前用户量比较大的一个在线笔记软件&#xff0c;它的文档系统也非常完善&#xff0c;支持多种文档格式&#xff0c;如 Markdown、富文本、表格、公式等。 早期我也用过一段时间&#xff0c;后来有点不习惯&#xff0c;就换到了 Obsidian &#xff0c;但是…

CSPM认证最推荐学习哪个级别?

一、什么是CSPM&#xff1f; CSPM的全称是Certified Strategic Project Manager&#xff0c;中文名称为“项目管理专业人员能力评价等级证书”。这是由中国标准化协会依据国家标准《项目管理专业人员能力评价要求》&#xff08;GB/T 41831-2022&#xff09;推出的一项认证&…

oracle: create new database

用database configuration Assistant 引导创建数据库。记得给system,sys 设置自己的口令&#xff0c;便于添加新操作用户。 创建操作用户&#xff1a; -- 别加双引号&#xff0c;否则&#xff0c;无法用 create user geovindu identified by 888888; create user geovin identi…

快速建站(网站如何在自己的电脑里跑起来) 详细步骤 一

1.选择开源网站 开源网站的建设平台有多种类型&#xff0c;每种类型都针对不同的需求和用途。我们根据自己的需求来选择 一、内容管理系统&#xff08;CMS&#xff09; 内容管理系统是开源网站建设中最常见的类型之一&#xff0c;它们提供了一个易于使用的界面&#xff0c;使用…

ECharts散点图-气泡图,附视频讲解与代码下载

引言&#xff1a; ECharts散点图是一种常见的数据可视化图表类型&#xff0c;它通过在二维坐标系或其它坐标系中绘制散乱的点来展示数据之间的关系。本文将详细介绍如何使用ECharts库实现一个散点图&#xff0c;包括图表效果预览、视频讲解及代码下载&#xff0c;让你轻松掌握…

【蓝桥杯——物联网设计与开发】拓展模块5 - 光敏/热释电模块

目录 一、光敏/热释电模块 &#xff08;1&#xff09;资源介绍 &#x1f505;原理图 &#x1f505;AS312 &#x1f319;简介 &#x1f319;特性 &#x1f505;LDR &#xff08;2&#xff09;STM32CubeMX 软件配置 &#xff08;3&#xff09;代码编写 &#xff08;4&#x…

Escalate_Linux靶机

Escalate_Linux靶机 前言&#xff1a;集合了多种liunx提权方法的靶场&#xff0c;通过该靶场可以简单的了解liunx提权方法 1&#xff0c;扫描一下端口 80/tcp open http 111/tcp open rpc 2049/udp nfs要知道对方的共享才能挂载 139/445 Samba SMB是一个协议名&#xff0c…

PPO算法基础(一)

PPO近端策略优化算法 我们今天还是主要来理解PPO算法的数学原理。PPO是一种策略梯度方法&#xff0c;简单的策略梯度对每个样本&#xff08;或者一组样本&#xff09;进行一次梯度更新&#xff0c;对单个样本执行多个梯度步骤会导致一些问题&#xff0c;因为梯度偏差太大&…

[机器学习]sklearn入门指南(1)

简介 scikit-learn&#xff08;简称sklearn&#xff09;是一个开源的Python机器学习库&#xff0c;它提供了简单而高效的工具用于数据挖掘和数据分析&#xff0c;并且拥有一个活跃的开发社区。它建立在NumPy、SciPy和matplotlib这些科学计算库之上&#xff0c;旨在提供一致且可…

贪心算法(三)

目录 一、k次取反后最大化的数组和 二、优势洗牌 三、最长回文串 四、增减字符串匹配 一、k次取反后最大化的数组和 k次取反后最大化的数组和 贪心策略&#xff1a; 解题代码&#xff1a; class Solution { public:int largestSumAfterKNegations(vector<int>&am…

文本的AIGC率检测原理

背景 你可能在学生群里或者视频中看过这样的消息&#xff1a;“我们学校要求论文AI率不能超过30%&#xff01;”、“你们学校查AI率吗&#xff1f;”之类的&#xff0c;这些消息到底是真是假&#xff1f; 随着人工智能的快速发展和广泛应用&#xff0c;不论是工作中还是学生学…

Linux -- 从抢票逻辑理解线程互斥

目录 抢票逻辑代码&#xff1a; thread.hpp thread.cc 运行结果&#xff1a; 为什么票会抢为负数&#xff1f; 概念前言 临界资源 临界区 原子性 数据不一致 为什么数据不一致&#xff1f; 互斥 概念 pthread_mutex_init&#xff08;初始化互斥锁&#xff09; p…

浅谈目前我开发的前端项目用到的设计模式

浅谈目前我开发的前端项目用到的设计模式 前言 设计模式很多&#xff0c;看到一个需求&#xff0c;项目&#xff0c;我们去开发的时候&#xff0c;肯定是做一个整体的设计进行开发&#xff0c;而在这次我项目中&#xff0c;我也做了一个整体的设计&#xff0c;为什么要设计&a…

ubuntu笔记

1.系统下载与虚拟机设置 系统下载https://cn.ubuntu.comhttps://releases.ubuntu.com 虚拟机设置: 桥接模式 在桥接模式下, 虚拟出来的操作系统就像是局域网中的一台独立的主机, 它可以访问网内任何一台机器主机网卡和虚拟网卡的IP地址处于同一个网段, 子网掩码、网关、DNS等…

开放世界目标检测 Grounding DINO

开放世界目标检测 Grounding DINO flyfish Grounding DINO 是一种开创性的开放集对象检测器&#xff0c;它通过结合基于Transformer的检测器DINO与基于文本描述的预训练技术&#xff0c;实现了可以根据人类输入&#xff08;如类别名称或指代表达&#xff09;检测任意对象的功…

【基础篇】1. JasperSoft Studio编辑器与报表属性介绍

编辑器介绍 Jaspersoft Studio有一个多选项卡编辑器&#xff0c;其中包括三个标签&#xff1a;设计&#xff0c;源代码和预览。 Design&#xff1a;报表设计页面&#xff0c;可以图形化拖拉组件设计报表&#xff0c;打开报表文件的主页面Source&#xff1a;源代码页码&#xff…