全面理解-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.rhkb.cn/news/16417.html

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

相关文章

基于java手机销售网站设计和实现(LW+源码+讲解)

专注于大学生项目实战开发,讲解,毕业答疑辅导&#xff0c;欢迎高校老师/同行前辈交流合作✌。 技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;…

初识计算机网络

从此篇我将开始网络新篇章&#xff01; 1. 网络发展史 最初的计算机之间相互独立存在&#xff0c;每个计算机只能持有自己的数据&#xff0c;数据无法共享。此时的计算机为独立模式 随着时代的发展&#xff0c;越来越需要计算机之间互相通信&#xff0c;共享软件和数据&#x…

PyTorch 中 `torch.cuda.amp` 相关警告的解决方法

在最近的写代码过程中&#xff0c;遇到了两个与 PyTorch 的混合精度训练相关的警告信息。这里随手记录一下。 警告内容 警告 1: torch.cuda.amp.autocast FutureWarning: torch.cuda.amp.autocast(args...) is deprecated. Please use torch.amp.autocast(cuda, args...) i…

【PS 2022】Adobe Genuine Service Alert 弹出

电脑总是弹出Adobe Genuine Service Alert弹窗 1. 不关掉弹窗并打开任务管理器&#xff0c;找到Adobe Genuine Service Alert&#xff0c;并右键进入文件所在位置 2 在任务管理器中结束进程并将文件夹中的 .exe 文件都使用空文档替换掉 3. 打开PS不弹出弹窗&#xff0c;解决&a…

Vue2生命周期面试题

在 Vue 2 中&#xff0c;this.$el 和 this.$data 都是 Vue 实例的属性&#xff0c;代表不同的内容。 1. this.$el this.$el 是 Vue 实例的根 DOM 元素&#xff0c;它指向 Vue 实例所控制的根节点元素。在 Vue 中&#xff0c;el 是在 Vue 实例创建时&#xff0c;指定的根元素&…

unity 安装Entities

因为Entities目前不支持用资源名动态加载资源&#xff01;没错&#xff0c;AssetsBundle或Addressables都不能用于Entities&#xff1b;也就意味着现阶段不能用Entities开发DLC或热更游戏。 Entities必须使用SubScene&#xff0c;而SubScene不能从资源动态加载&#xff0c;路被…

基于 PyTorch 的树叶分类任务:从数据准备到模型训练与测试

基于 PyTorch 的树叶分类任务&#xff1a;从数据准备到模型训练与测试 1. 引言 在计算机视觉领域&#xff0c;图像分类是一个经典的任务。本文将详细介绍如何使用 PyTorch 实现一个树叶分类任务。我们将从数据准备开始&#xff0c;逐步构建模型、训练模型&#xff0c;并在测试…

团结引擎 Shader Graph:解锁图形创作新高度

Shader Graph 始终致力于为开发者提供直观且高效的着色器构建工具&#xff0c;持续推动图形渲染创作的创新与便捷。在团结引擎1.4.0中&#xff0c;Shader Graph 迎来了重大更新&#xff0c;新增多项强大功能并优化操作体验&#xff0c;助力开发者更轻松地实现高质量的渲染效果与…

C# OpenCV机器视觉:模仿Halcon各向异性扩散滤波

在一个充满创意与挑战的图像处理工作室里&#xff0c;阿强是一位热情的图像魔法师。他总是在追求更加出色的图像效果&#xff0c;然而&#xff0c;传统的图像处理方法有时候并不能满足他的需求。 有一天&#xff0c;阿强听说了 Halcon 中的各向异性扩散滤波功能&#xff0c;它…

超详细的数据结构3(初阶C语言版)栈和队列。

文章目录 栈和队列1.栈1.1 概念与结构1.2 栈的实现 2. 队列2.1 概念与结构2.2 队列的实现 总结 栈和队列 1.栈 1.1 概念与结构 栈&#xff1a;⼀种特殊的线性表&#xff0c;其只允许在固定的⼀端进行插⼊和删除元素操作。进⾏数据插⼊和删除操作的⼀端称为栈顶&#xff0c;另…

利用邮件合并将Excel的信息转为Word(单个测试用例转Word)

利用邮件合并将Excel的信息转为Word 效果一览效果前效果后 场景及问题解决方案 一、准备工作准备Excel数据源准备Word模板 二、邮件合并操作步骤连接Excel数据源插入合并域预览并生成合并文档 效果一览 效果前 效果后 场景及问题 在执行项目时的验收阶段&#xff0c;对于测试…

一个基于ESP32S3和INMP441麦克风实现音频强度控制RGB灯带律动的代码及效果展示

一个基于ESP32S3和INMP441麦克风实现音频强度控制RGB灯带律动的代码示例&#xff0c;使用Arduino语言&#xff1a; 硬件连接 INMP441 VCC → ESP32的3.3VINMP441 GND → ESP32的GNDINMP441 SCK → ESP32的GPIO 17INMP441 WS → ESP32的GPIO 18INMP441 SD → ESP32的GPIO 16RG…

用户认证综合实验

实验需求 需求一&#xff1a;根据下表&#xff0c;完成相关配置 需求二&#xff1a;配置DHCP协议&#xff0c;具体要求如下 需求三&#xff1a;防火墙安全区域配置 需求四&#xff1a;防火墙地址组信息 需求五&#xff1a;管理员 为 FW 配置一个配置管理员。要求管理员可以通…

Curser2_解除机器码限制

# Curser1_无限白嫖试用次数 文末有所需工具下载地址 Cursor Device ID Changer 一个用于修改 Cursor 编辑器设备 ID 的跨平台工具集。当遇到设备 ID 锁定问题时&#xff0c;可用于重置设备标识。 功能特性 ✨ 支持 Windows 和 macOS 系统&#x1f504; 自动生成符合格式的…

linux部署node服务

1、安装nvm管理node版本 # 下载、解压到指定目录 wget https://github.com/nvm-sh/nvm/archive/refs/tags/v0.39.1.tar.gz tar -zxvf nvm-0.39.0.tar.gz -C /opt/nvm # 配置环境 vim ~/.bashrc~&#xff1a;这是一个路径简写符号&#xff0c;代表当前用户的主目录。在大多数 …

Kotlin实战经验:将接口回调转换成suspend挂起函数

在 Kotlin 协程中, suspendCoroutine 和 suspendCancellableCoroutine 是用于将回调或基于 future 的异步操作转换成挂起函数。 suspendCoroutine 用途:将回调式异步操作转换为可挂起函数 行为: 启动一个新的协程来处理基于回调的操作挂起当前协程,直到调用回调回调负责…

【DeepSeek服务器繁忙,请稍后再试...如何解决?】

DeepSeek服务器繁忙&#xff0c;请稍后再试...如何解决&#xff1f; DeepSeek该咋使用&#xff1f;解决办法&#xff1a;本地桌面工具接下来说下&#xff0c;DeepSeek提示词该咋写&#xff1f; DeepSeek该咋使用&#xff1f; 首先&#xff0c;先说下DeepSeek该咋使用&#xff…

SDKMAN! 的英文全称是 Software Development Kit Manager(软件开发工具包管理器)

文章目录 SDKMAN! 的核心功能SDKMAN! 的常用命令SDKMAN! 的优势总结 SDKMAN! 的英文全称是 Software Development Kit Manager。它是一个用于管理多个软件开发工具&#xff08;如 Java、Groovy、Scala、Kotlin 等&#xff09;版本的工具。SDKMAN! 提供了一个简单的方式来安装、…

Python实现GO鹅优化算法优化支持向量机SVM分类模型项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后关注获取。 1.项目背景 随着信息技术的迅猛发展&#xff0c;数据量呈爆炸式增长&#xff0c;如何从海量的数据中提取有价值…

网络安全工程师逆元计算 网络安全逆向

中职逆向题目整理合集 逆向分析&#xff1a;PE01.exe算法破解&#xff1a;flag0072算法破解&#xff1a;flag0073算法破解&#xff1a;CrackMe.exe远程代码执行渗透测试天津逆向re1 re22023江苏省re12023年江苏省赛re2_easygo.exe2022天津市PWN 逆向分析&#xff1a;PE01.exe …