全面理解-c++中的异常处理机制

C++ 的异常处理机制是一种用于处理程序运行时错误的结构化方法,通过分离正常逻辑与错误处理代码,提高代码的可读性和可维护性。以下是其核心组成部分和工作原理的详细说明:


1. 异常处理的三大关键字

1.1 try 块
  • 作用:包裹可能抛出异常的代码段。

  • 语法

    try {// 可能抛出异常的代码
    }
1.2 throw 表达式
  • 作用:抛出异常对象(可以是任意类型,但通常继承自 std::exception)。

  • 语法

    throw exception_object;
1.3 catch 块
  • 作用:捕获并处理特定类型的异常。

  • 语法

    catch (ExceptionType1& e) {// 处理 ExceptionType1 异常
    } catch (ExceptionType2& e) {// 处理 ExceptionType2 异常
    } catch (...) { // 捕获所有异常// 处理未知异常
    }

2. 异常处理流程

  1. 抛出异常:代码执行到 throw 时,立即停止当前函数,开始栈展开(Stack Unwinding)。

  2. 栈展开

    • 析构当前作用域的局部对象(按构造逆序)。

    • 沿调用链向上查找匹配的 catch 块。

  3. 捕获异常:找到第一个匹配的 catch 块后执行其代码。

  4. 未捕获异常:若未找到匹配的 catch 块,调用 std::terminate() 终止程序。


3. 异常类型与捕获方式

3.1 标准异常类

C++ 标准库定义了一组异常类(位于 <stdexcept> 头文件),均继承自 std::exception

  • std::logic_error:程序逻辑错误(如 std::invalid_argument)。

  • std::runtime_error:运行时错误(如 std::overflow_error)。

  • 自定义异常通常继承自 std::exception

    class MyException : public std::exception {
    public:const char* what() const noexcept override {return "My custom exception";}
    };
3.2 捕获方式
  • 按值捕获:拷贝异常对象(可能引发切片问题)。

  • 按引用捕获:避免拷贝,保留多态性(推荐)。

  • 按指针捕获:需手动管理内存(不推荐)。

  • 捕获所有异常catch (...)(通常用于日志记录或资源清理)。


4. 异常安全性

函数在抛出异常时需保证资源不泄漏,分为三个级别:

  1. 基本保证(Basic Guarantee):异常发生后,程序处于合法状态。

  2. 强保证(Strong Guarantee):操作要么完全成功,要么回滚到操作前的状态(事务语义)。

  3. 不抛保证(No-throw Guarantee):承诺不抛出任何异常(用 noexcept 标记)。


5. 关键机制与注意事项

5.1 noexcept 关键字
  • 作用:声明函数不会抛出异常,帮助编译器优化代码。

  • 语法

    void func() noexcept; // C++11 起
5.2 栈展开与析构
  • RAII(Resource Acquisition Is Initialization):依赖对象的析构函数自动释放资源(如智能指针、文件句柄)。

  • 避免在析构函数中抛出异常:可能导致程序终止。

5.3 性能影响
  • 零开销原则:无异常时代码无额外开销。

  • 抛出异常时开销较大:涉及栈展开和类型匹配,避免频繁使用异常处理常规逻辑。


6. 代码示例

6.1 基本用法
#include <iostream>
#include <stdexcept>void riskyOperation(int value) {if (value < 0) {throw std::invalid_argument("Value cannot be negative");}// 其他操作
}int main() {try {riskyOperation(-5);} catch (const std::invalid_argument& e) {std::cerr << "Error: " << e.what() << std::endl;} catch (...) {std::cerr << "Unknown error occurred" << std::endl;}return 0;
}
6.2 自定义异常
#include <exception>
#include <string>class NetworkError : public std::exception {
private:std::string message;
public:NetworkError(const std::string& msg) : message(msg) {}const char* what() const noexcept override {return message.c_str();}
};void connectToServer() {throw NetworkError("Connection timeout");
}

7. 最佳实践

  1. 优先使用标准异常类型,保持异常层次清晰。

  2. 按引用捕获异常,避免对象切片和多态丢失。

  3. 利用 RAII 管理资源,确保异常安全。

  4. 避免在构造函数中抛出异常,除非能完全清理资源。

  5. 用 noexcept 标记不会抛出异常的函数,提升性能。


总结

C++ 异常处理通过 try/catch/throw 提供了一种结构化的错误管理机制,结合 RAII 和标准异常类,可以有效提升代码的健壮性。合理使用异常处理需权衡性能与安全性,遵循异常安全等级和最佳实践。

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

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

相关文章

支持向量机原理

支持向量机&#xff08;简称SVM&#xff09;虽然诞生只有短短的二十多年&#xff0c;但是自一诞生便由于它良好的分类性能席卷了机器学习领域。如果不考虑集成学习的算法&#xff0c;不考虑特定的训练数据集&#xff0c;尤其在分类任务中表现突出。在分类算法中的表现SVM说是排…

zy.21

PHP(续) PHP代码执行漏洞 1.PHP中代码漏洞的概念 代码执行漏洞就是在代码中若存在eval、assert等能将所接收的参数作为代码去执行,并且拼接的内容可被访问者控制,也就是把传入的参数给拼接进去了,造成了额外的代码执行,也就造成了代码执行漏洞。&#xff08;大概原理&#x…

LSTM 学习笔记 之pytorch调包每个参数的解释

0、 LSTM 原理 整理优秀的文章 LSTM入门例子&#xff1a;根据前9年的数据预测后3年的客流&#xff08;PyTorch实现&#xff09; [干货]深入浅出LSTM及其Python代码实现 整理视频 李毅宏手撕LSTM [双语字幕]吴恩达深度学习deeplearning.ai 1 Pytorch 代码 这里直接调用了nn.l…

React - 事件绑定this

在 React 中&#xff0c;this 的绑定是一个常见问题&#xff0c;尤其在类组件中使用事件处理函数时。JavaScript 中的 bind 函数用于设置函数调用时 this 的值。 bind 函数的作用 bind() 方法创建一个新的函数&#xff0c;当被调用时&#xff0c;其 this 关键字被设置为提供的…

Web3 的虚实融合之路:从虚拟交互到元宇宙构建

在这个数字技术日新月异的时代&#xff0c;我们正站在 Web3 的门槛上&#xff0c;见证着互联网的又一次革命。Web3 不仅仅是技术的迭代&#xff0c;它代表了一种全新的交互方式和价值创造模式。本文将探讨 Web3 如何推动虚拟交互的发展&#xff0c;并最终实现元宇宙的构建&…

Kafka简单使用

说明&#xff1a;kafka是一款消息中间件&#xff0c;可实现微服务之间的异步调用。本文介绍kafka的简单使用。windows操作系统下的kafka安装&#xff0c;参考下面这篇文章 Kafka安装 启动 按照上面博客的介绍&#xff0c;使用CMD命令启动&#xff0c;如下&#xff1a; Demo …

【原创精品】基于Springboot3+Vue3的学习计划管理系统

大家好&#xff0c;我是武哥&#xff0c;最近给大家手撸了一个基于SpringBoot3Vue3的学习计划管理系统&#xff0c;可用于毕业设计、课程设计、练手学习&#xff0c;系统全部原创&#xff0c;如有遇到网上抄袭站长的&#xff0c;欢迎联系博主~ 项目演示视频 https://www.bili…

为什么我用Python控制仪器比C#慢很多?如何优化性能?

在自动化测试、实验室仪器控制等领域&#xff0c;Python、C# 和 C 是常见的编程语言选择。最近&#xff0c;我在使用 Python 控制仪器时&#xff0c;发现其交互速度明显比 C# 慢很多。这让我感到困惑&#xff0c;毕竟 Python 以其简洁和高效著称&#xff0c;为什么会出现这种情…

在Vue项目中Vuex和松花的作用和区别

在 Vue 项目中&#xff0c;Vuex 和 Pinia 都是用于状态管理的工具&#xff0c;但它们在设计理念、使用方式和性能等方面存在显著区别。以下是它们的作用和区别&#xff1a; 作用 Vuex&#xff1a; Vuex 是 Vue.js 的官方状态管理库&#xff0c;主要用于管理组件之间的共享状态…

微服务日志查询难解决方案-EFK

前言 在微服务项目中&#xff0c;日志查询难是一个常见问题&#xff0c;主要原因包括&#xff1a;日志分散&#xff1a;微服务实例分布在多个节点或容器中&#xff0c;日志存储位置分散。格式不统一&#xff1a;不同服务可能使用不同的日志格式&#xff0c;难以统一查询。调用…

为AI聊天工具添加一个知识系统 之90 详细设计之31 Derivation 之5-- 神经元变元用它衍生神经网络

本文要点 要点 Derivation 神经元变元衍生模型&#xff08; 衍生 神经网络&#xff09; 整体上说&#xff0c;它&#xff08; Derivation&#xff09;自己充当 整体无意识原型anestor的代言--作为所有神经网络的 共生环境。Derivation 初始断言了 基于最古老的 自然和逻辑树…

C++引用深度详解

C引用深度详解 前言1. 引用的本质与核心特性1.1 引用概念1.2 核心特性 2. 常引用与权限控制2.1 权限传递规则2.2 常量引用2.3 临时变量保护1. 样例2. 样例3. 测试 三、引用使用场景分析3.1 函数参数传递输出型参数避免多级指针高效传参 3.2 做函数返回值正确使用危险案例 4. 性…

若依框架二次开发——若依介绍、环境部署及更换项目包路径

文章目录 一、若依介绍1、项目简介2、主要特性3、技术选型4、内置功能5、文件结构6、配置文件7、核心技术介绍二、环境部署1、准备工作2、运行系统3、必要配置4、部署系统三、更换项目包路径1、更换目录名称2、更换顶级目录中的pom.xml3、更换项目所有包名称4、修改application…

本地部署Deepseek R1

使用Ollama open-webui部署Deepseek R1 一、安装Ollama 官网地址&#xff1a;https://ollama.com/&#xff0c;点击下载按钮选择windows版本。并安装 打开命令提示符输入ollama&#xff0c;出现一下提示命令表示ollama安装完成 二、使用Ollama下载deepseek R1不同模型 打开o…

速度超越DeepSeek!Le Chat 1100tok/s闪电回答,ChatGPT 4o和DeepSeek R1被秒杀?

2023年&#xff0c;当全球科技界还在ChatGPT引发的AI狂潮中沉浮时&#xff0c;一场来自欧洲的"静默革命"正悄然改变游戏规则。法国人工智能公司Mistral AI推出的聊天机器人Le Chat以"比ChatGPT快10倍"的惊人宣言震动业界&#xff0c;其背后承载的不仅是技术…

MATLAB 生成脉冲序列 pulstran函数使用详解

MATLAB 生成脉冲序列 pulstran函数使用详解 目录 前言 一、参数说明 二、示例一 三、示例二 总结 前言 MATLAB中的pulstran函数用于生成脉冲序列&#xff0c;支持连续或离散脉冲。该函数通过将原型脉冲延迟并相加&#xff0c;生成脉冲序列&#xff0c;适用于信号处理和系统…

ASP.NET Core的贫血模型与充血模型

目录 概念 需求 贫血模型 充血模型 总结 概念 贫血模型&#xff1a;一个类中只有属性或者成员变量&#xff0c;没有方法。充血模型&#xff1a;一个类中既有属性、成员变量&#xff0c;也有方法。 需求 定义一个类保存用户的用户名、密码、积分&#xff1b;用户必须具有…

机器学习(李宏毅)——self-Attention

一、前言 本文章作为学习2023年《李宏毅机器学习课程》的笔记&#xff0c;感谢台湾大学李宏毅教授的课程&#xff0c;respect&#xff01;&#xff01;&#xff01; 二、大纲 何为self-Attention&#xff1f;原理剖析self-Attention VS CNN、RNN、GNN 三、何为self-Attenti…

RagFlow + Docker Desktop + Ollama + DeepSeek-R1本地部署自己的本地AI大模型工具

前期准备 首先&#xff0c;我们需要下载 Ollama 以及配置相关环境。 Ollama 的 GitHub仓库 &#xff08;https://github.com/ollama/ollama&#xff09;中提供了详细的说明&#xff0c;简单总结如下: Step1&#xff1a;下载 Ollama 下载&#xff08;https://ollama.com/dow…

【数据结构】双向链表(真正的零基础)

链表是一种物理存储单元上非连续、非顺序的存储结构。数据元素的逻辑顺序是通过指针的链接来实现的&#xff01;在上篇我们学习了单向链表&#xff0c;而单向链表虽然空间利用率高&#xff0c;插入和删除也只需改变指针就可以达到&#xff01;但是我们在每次查找、删除、访问..…