当前位置: 首页 > news >正文

C++异常的深入了解

C++ 异常是处理运行时错误的标准化机制,核心价值是将「错误检测」与「错误处理」解耦,彻底替代传统的错误码返回方式,让代码逻辑更清晰、健壮。

1.异常概念

异常(Exception)是 C++ 中用于处理程序运行时错误的一种机制。当程序遇到无法正常执行的情况(如除以零、内存分配失败等),可以通过抛出异常中断当前流程,并由专门的异常处理代码捕获和处理。

2.异常的三要素

C++ 异常通过三个关键字实现:try、throw、catch

基础语法:

#include <iostream> using namespace std; void test(int a) { // 1. throw:抛出异常对象(任意类型,推荐类类型) if (a == 0) throw "除数不能为零!"; // 抛字符串 if (a < 0) throw invalid_argument("负数不合法!"); // 抛标准异常 cout << 100 / a << endl; } int main() { try { // 2. try:包裹「可能抛出异常」的代码 test(0); } // 3. catch:捕获匹配类型的异常 catch (const char* e) { cout << "捕获字符串异常:" << e << endl; } catch (const invalid_argument& e) { cout << "捕获标准异常:" << e.what() << endl; } return 0; }

核心规则:
1.try 块:仅包裹可能出错的代码,无异常则正常执行;
2.throw:抛出后立即中断当前执行流,不会执行后续代码;
3.catch:按类型严格匹配异常,捕获后执行处理逻辑。

3.栈展开

这是 C++ 异常最关键的底层机制,也是异常能自动释放资源的根本原因:
1.抛出异常时,程序停止当前执行;
2.从 throw 所在函数开始,逐层回退函数调用栈;
3.每退出一层函数,自动销毁该函数的所有局部对象(调用析构函数);
4.直到找到匹配的 catch 块,程序恢复执行;
5.若全程无匹配 catch,调用 std::terminate 直接终止程序。

代码演示栈展开:

#include <iostream> using namespace std; // 测试对象:构造/析构打印日志 class Test { public: Test() { cout << "Test 构造" << endl; } ~Test() { cout << "Test 析构" << endl; } }; void func2() { Test t; // 局部对象 throw "抛出异常!"; // 抛出异常 cout << "func2 后续代码(不会执行)" << endl; } void func1() { func2(); } int main() { try { func1(); } catch (const char* e) { cout << "捕获异常:" << e << endl; } return 0; }

执行结果:

Test 构造 Test 析构 ✅ 栈展开:自动销毁局部对象 捕获异常:抛出异常!

4.异常捕获的高级规则

1. 类型匹配:无隐式转换
异常捕获不支持隐式类型转换(如 int ↔ double),必须严格匹配类型。
2. 继承类异常:派生类优先捕获
如果抛出派生类异常,catch 必须把派生类写在基类前面,否则会被基类截断(对象切片)。

// 基类异常 class BaseEx {}; // 派生类异常 class DeriveEx : public BaseEx {}; try { throw DeriveEx(); } // ✅ 正确:派生类在前 catch (const DeriveEx& e) { cout << "捕获派生类" << endl; } catch (const BaseEx& e) { cout << "捕获基类" << endl; }

5.万能捕获:catch(...)

捕获所有未匹配的异常,通常用于兜底,避免程序崩溃:

catch (...) { cout << "捕获未知异常!" << endl; // 可以重新抛出:throw; }

推荐:按引用捕获异常
避免对象拷贝,提升性能;
避免继承类的对象切片问题;
标准写法:catch (const 异常类型& e)

谢谢
http://www.jsqmd.com/news/973256/

相关文章:

  • 嵌入式网络调试避坑实录:W5500驱动集成中SPI片选(CS)与中断的那些‘坑’
  • 安卓端摄像头实时测心率开发套件(含APP源码、服务端、数据库脚本与实操演示)
  • Python中文NLP实战:从预处理避坑到轻量模型部署
  • C++特殊类设计(详细介绍)
  • 宝兰德BES中间件分离部署实战:用两个账号搞定生产环境安全隔离(附详细命令)
  • 基于STC89C52的三温区冰箱控制器:带DS18B20测温、机械式除霜检测、数码管/LCD双显示方案
  • 别再到处找了!我整理了全套Apriltag tag36H11视觉标定图(附高清下载链接)
  • 联盛德W806驱动ST7567液晶屏避坑指南:硬件SPI配置、内存偏移处理与对比度调校
  • 30张实拍舰船图+XML/TXT双标注,开箱即用YOLOv5训练
  • CAN错误处理机制:错误计数、错误状态和总线关闭
  • 2026年实测保姆级指南:查重AIGC爆表?豆包4大神仙指令+3款免费降AI工具降至5%! - 降AI实验室
  • Hadoop学习教程,从入门到精通, 初识Hadoop — 知识点详解(1)
  • C# WPF超市收银桌面程序源码包,含UI界面、数据访问层与完整运行截图
  • 从自动驾驶到电机控制:聊聊卡尔曼滤波这位‘跨界大神’的降维应用
  • 央视连发三条专题!济南AI模型工厂:75道工序流水线量产,一年“造“出1000+模型
  • 2026年众智商学院中级经济师上班族晚间班期费用资料怎么核对?官网400冯老师 - 众智商学院官方
  • 华硕笔记本性能管理神器:G-Helper轻量级控制工具完全指南
  • 2026年众智商学院PMP官网咨询入口:怎么报名和怎么选班期领取资料 - 众智商学院官方
  • MATLAB实现GNSS+IMU组合导航仿真:EKF融合算法全流程可运行代码包
  • JavaScript数组遍历性能与兼容性深度解析
  • 从GPS到北斗:手把手教你用Python解析NMEA-0183数据(附完整代码)
  • 手机存储速度翻倍的秘密:一文读懂UFS 2.2里的M-PHY物理层(附避坑指南)
  • 3步解决图像模糊难题:用vectorizer实现PNG/JPG到SVG的无损转换
  • 手把手教你配置TMS320F28335的SPI模块(含FIFO模式与自测代码)
  • AI Agent 运行时重构:会话即日志与无状态执行引擎
  • Open3D GUI踩坑实录:从‘Hello Sphere’到流畅3D界面的五个关键配置
  • 2026出圈!5款AI论文写作软件亲测,摆脱无效加班,初稿质量效率翻倍
  • 从0到1构建生产级RAG系统:架构、实战与避坑指南
  • Windows服务器可用的ASP电视直播站源码,含播放页与后台管理全套文件
  • 【MySQL | 第七篇】 索引使用规则