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

news2025/2/11 15:25:04

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.coloradmin.cn/o/2296384.html

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

相关文章

Deep Dive into LLMs like ChatGPT - by Andrej Karpathy

https://www.youtube.com/watch?v7xTGNNLPyMIhttps://www.youtube.com/watch?v7xTGNNLPyMIDeep Dive into LLMs like ChatGPT - by Andrej Karpathy_哔哩哔哩_bilibilihttps://www.youtube.com/watch?v7xTGNNLPyMI转载自Andrej Karpathy Youtube ChannelThis is a general a…

react实例与总结(一)

目录 一、简单认识 1.1、特点 1.2、JSX语法规则 1.3、函数组件和类式组件 1.4、类组件三大属性state、props、refs 1.4.1、state 1.4.2、props 1.4.3、refs 1.5、事件处理 1.6、收集表单数据—非受控组件和受控组件 1.7、高阶函数—函数柯里化 1.8、生命周期—新旧…

51单片机(国信长天)矩阵键盘的基本操作

在CT107D单片机综合训练平台上&#xff0c;首先将J5处的跳帽接到1~2引脚&#xff0c;使按键S4~S19按键组成4X4的矩阵键盘。在扫描按键的过程中&#xff0c;发现有按键触发信号后(不做去抖动)&#xff0c;待按键松开后&#xff0c;在数码管的第一位显示相应的数字:从左至右&…

STM32 RTC亚秒

rtc时钟功能实现&#xff1a;rtc模块在stm32内部&#xff0c;由电池或者主电源供电。如下图&#xff0c;需注意实现时仅需设置一次初始化。 1、stm32cubemx 代码生成界面设置&#xff0c;仅需开启时钟源和激活日历功能。 2、生成的代码,需要对时钟进行初始化&#xff0c;仅需…

【Linux】深入理解linux权限

&#x1f31f;&#x1f31f;作者主页&#xff1a;ephemerals__ &#x1f31f;&#x1f31f;所属专栏&#xff1a;Linux 目录 前言 一、权限是什么 二、用户和身份角色 三、文件属性 1. 文件属性表示 2. 文件类型 3. 文件的权限属性 四、修改文件的权限属性和角色 1. …

json格式,curl命令,及轻量化处理工具

一. JSON格式 JSON&#xff08;JavaScript Object Notation&#xff09; 是一种轻量级的数据交换格式。它基于一个子集的JavaScript编程语言&#xff0c;使用人类易于阅读的文本格式来存储和表示数据。尽管名字中有“JavaScript”&#xff0c;但JSON是语言无关的&#xff0c;几…

web直播弹幕抓取分析 signature

声明: 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01; 前言 最近遇到太多难点了卡了很久&am…

ABP框架9——自定义拦截器的实现与使用

一、AOP编程 AOP定义:面向切片编程&#xff0c;着重强调功能&#xff0c;将功能从业务逻辑分离出来。AOP使用场景&#xff1a;处理通用的、与业务逻辑无关的功能&#xff08;如日志记录、性能监控、事务管理等&#xff09;拦截器:拦截方法调用并添加额外的行为&#xff0c;比如…

CUDA 计算平台 CUDA 兼容性【笔记】

在 b 站看过的两个关于 CUDA 的技术分享&#xff0c;整理分享下对自己有用的课件。 20231130 2023第9期 聊一聊常见的AI计算平台库_哔哩哔哩_bilibili20230831 2023第6期 聊一聊CUDA兼容性_哔哩哔哩_bilibili 文章目录 CUDA 计算平台CUDA 函数库介绍英伟达三大护城河&#xff1…

最新消息 | 德思特荣获中国创新创业大赛暨广州科技创新创业大赛三等奖!

2024年12月30日&#xff0c;广州市科技局公开第十三届中国创新创业大赛&#xff08;广东广州赛区&#xff09;暨2024年广州科技创新创业大赛决赛成绩及拟获奖企业名单&#xff0c;德思特获得了智能与新能源汽车初创组【第六名】【三等奖】的好成绩&#xff01; 关于德思特&…

ubuntu安装VMware报错/dev/vmmon加载失败

ubuntu安装VMware报错/dev/vmmon加载失败&#xff0c;解决步骤如下&#xff1a; step1&#xff1a;为vmmon和vmnet组件生成密钥对 openssl req -new -x509 -newkey rsa:2048 -keyout VMW.priv -outform DER -out VMW.der -nodes -days 36500 -subj "/CNVMware/"ste…

python的列表、元组、深拷贝、浅拷贝(四)

python的列表 一、序列1. 序列定义2. 序列数据类型包括3.特点&#xff1a;都支持下面的特性 二、 列表1. 列表的创建2. 列表的基本特性(1) 连接操作符喝重复操作符(2) 成员操作符&#xff08;in , not in &#xff09;(3) 索引(4) 切片练习(5) for循环 3. 列表的常用方法(1) 一…

2.10作业

思维导图 C C语言

【深度学习】多目标融合算法(四):多门混合专家网络MMOE(Multi-gate Mixture-of-Experts)

目录 一、引言 二、MMoE&#xff08;Multi-gate Mixture-of-Experts&#xff0c;多门混合专家网络&#xff09; 2.1 技术原理 2.2 技术优缺点 2.3 业务代码实践 2.3.1 业务场景与建模 2.3.2 模型代码实现 2.3.3 模型训练与推理测试 2.3.4 打印模型结构 三、总结 一、…

RuoYi-Vue-Oracle的oracle driver驱动配置问题ojdbc8-12.2.0.1.jar的解决

RuoYi-Vue-Oracle的oracle driver驱动配置问题ojdbc8-12.2.0.1.jar的解决 1、报错情况 下载&#xff1a;https://gitcode.com/yangzongzhuan/RuoYi-Vue-Oracle 用idea打开&#xff0c;启动&#xff1a; 日志有报错&#xff1a; 点右侧m图标&#xff0c;maven有以下报误 &…

C# OpenCV机器视觉:对位贴合

在热闹非凡的手机维修街上&#xff0c;阿强开了一家小小的手机贴膜店。每天看着顾客们自己贴膜贴得歪歪扭扭&#xff0c;不是膜的边缘贴不整齐&#xff0c;就是里面充满了气泡&#xff0c;阿强心里就想&#xff1a;“要是我能有个自动贴膜的神器&#xff0c;那该多好啊&#xf…

Baumer工业相机堡盟相机的相机传感器芯片清洁指南

Baumer工业相机堡盟相机的相机传感器芯片清洁指南 Baumer工业相机1.Baumer工业相机传感器芯片清洁工具和清洁剂2.Baumer工业相机传感器芯片清洁步骤2.1、准备步骤2.2、清洁过程1.定位清洁工具2.清洁传感器3&#xff0e;使用吹风装置 Baumer工业相机传感器芯片清洁的优势设计与结…

《我在技术交流群算命》(三):QML的Button为什么有个蓝框去不掉啊(QtQuick.Controls由Qt5升级到Qt6的异常)

有群友抛出类似以下代码和运行效果截图&#xff1a; import QtQuick import QtQuick.ControlsWindow {width: 640height: 480visible: truetitle: qsTr("Hello World")Button{anchors.centerIn: parentwidth: 100height: 40background: Rectangle {color: "red…

Golang:Go 1.23 版本新特性介绍

流行的编程语言Go已经发布了1.23版本&#xff0c;带来了许多改进、优化和新特性。在Go 1.22发布六个月后&#xff0c;这次更新增强了工具链、运行时和库&#xff0c;同时保持了向后兼容性。 Go 1.23 的新增特性主要包括语言特性、工具链改进、标准库更新等方面&#xff0c;以下…

在 PyTorch 中理解词向量,将单词转换为有用的向量表示

你要是想构建一个大型语言模型&#xff0c;首先得掌握词向量的概念。幸运的是&#xff0c;这个概念很简单&#xff0c;也是本系列文章的一个完美起点。 那么&#xff0c;假设你有一堆单词&#xff0c;它可以只是一个简单的字符串数组。 animals ["cat", "dog…