news 2026/4/29 17:24:40

异常、捕获、catch、throw与noexcept

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
异常、捕获、catch、throw与noexcept

异常

异常的概念及应用

异常的概念

异常是程序运行时出现不符预期的反常情况,有时由于异常的广泛性我们无法考虑到所有的异常情况因此处理异常(不然怎么叫作"异常"?),所以我们是尽量在可检测原因的范围内进行捕获与抛出,所以异常的检测只是初步检测真正的异常原因常常需要亲自去查找。

异常的抛出与捕获

例:在try内检测可能异常抛出(throw)的对象,接收(catch)对象+输出异常原因

//除法的函数定义 double Divide(int a, int b) { try { // 当b == 0时抛出异常 if (b == 0) { string s("Divide by zero condition!"); throw s; } else { return ((double)a / (double)b); } } catch (string errid)//异常的值会被存储到 errid变量中,供 catch 块内部使用 { cout << errid << endl; } return 0; }

注:throw不一定在try内,抛出throw的本质是为了寻找匹配的catch语句。

异常的接收规则:

接收被抛出对象时,其匹配类型匹配且离抛出位置最近的那个接收(catch)对象(可能在同一作用域也可能在不同作用域)。
抛出(throw)后(抛出的是对象的拷贝资源)直接跳转到catch语句,因此throw后的语句不会再执行,若出函数则相应函数栈帧销毁。在开发时要额外注意此点。
抛出对象的拷贝资源在catch语句结束后会销毁。

栈展开

抛出异常后,程序暂停当前函数的执行,开始寻找与之匹配的catch语句,首先检查throw本身是否在try内若不在且位于被外界调用函数内,那么跳转出当前函数继续寻找……如果到达main()函数依旧没有找到那么调用库内terminal函数来抛出异常:

由此库内函数的调用机制可以看出这种异常抛出是脱离于操控范围内、极其危险的程序性错误。

catch的全捕捉

因此catch提供catch(...)全捕捉函数来一定捕获程序出现的所有异常:

catch (...) { cout << "未知异常,请及时查找!"; }

catch匹配的宽泛型处理代码

what()是异常抛出的库内函数处理,检测调用对象的异常情况并抛出。

1.允许非常量向常量类型转换(权限缩小)。
2.允许数组转换为数组的指针,函数被转换为函数指针。
※3.允许派生类向基类的转换。

class Base { public: virtual void what() const { cout << "Base exception" << endl; } }; // Base衍生的 class Derived : public Base { public: void what() const override { cout << "Derived exception" << endl; } }; int main() { try { Derived d; if(…………) throw d; } catch (const Base& b)//隐式转换为基类对象 { cout << b.what(); //或者: b.what(); } return 0; }

异常重新抛出

"重新抛出"的性质是再次重复调用尝试解决异常:(如:网络波动、手机信号)

下面代码展示:发送信息失败后重复三次再不成功抛异常

void _SeedMsg(const string & s) { if (……) { //内部抛异常 throw HttpException("⽹络不稳定,发送失败", 102, "put"); } else if (……) { //内部抛异常 throw HttpException("你已经不是对象的好友,发送失败", 103, "put"); } else { cout << "发送成功" << endl; } } void SendMsg(const string & s) { // 发送消息失败,则再重试3次 for (size_t i = 0; i < 4; i++) { try { _SeedMsg(s); break; }//外部catch catch (const Exception& e) { // 捕获异常,if中是102号错误,⽹络不稳定,则重新发送 // 捕获异常,else中不是102号错误,则将异常重新抛出 if (e.getid() == 102) { // 重试三次以后否失败了,则说明⽹络太差了,重新抛出异常 if (i == 3) throw; cout << "开始第" << i + 1 << "重试" << endl; } else { throw; } } } }

异常规范(noexcept)

在函数后加"noexcept"明确表示此函数不会抛异常不用进行try内检测。

noexcept的不规范使用:
引发原因:编译器不会再编译期间检查noexcept,也就是说如果一个声明了noexcept的函数内部使用throw抛出异常经编译器不会catch寻找会直接调用terminate库函数终止程序

noexcept(expression)可作为一个运算符检测一个表达式是否可能会抛出异常,可能返回true,不可能返回false。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/29 17:20:39

Ultimate ASI Loader:3分钟学会游戏模组零基础安装指南

Ultimate ASI Loader&#xff1a;3分钟学会游戏模组零基础安装指南 【免费下载链接】Ultimate-ASI-Loader The Ultimate ASI Loader is a proxy DLL that loads custom .asi libraries into any game process. 项目地址: https://gitcode.com/gh_mirrors/ul/Ultimate-ASI-Loa…

作者头像 李华
网站建设 2026/4/29 17:15:27

Apollo Save Tool:你的PS4游戏存档终极管理解决方案

Apollo Save Tool&#xff1a;你的PS4游戏存档终极管理解决方案 【免费下载链接】apollo-ps4 Apollo Save Tool (PS4) 项目地址: https://gitcode.com/gh_mirrors/ap/apollo-ps4 还在为PS4游戏存档备份困难、无法跨账户使用而烦恼吗&#xff1f;想要轻松管理游戏进度&am…

作者头像 李华
网站建设 2026/4/29 17:14:41

Winhance中文版:让你的Windows系统性能翻倍的终极优化指南

Winhance中文版&#xff1a;让你的Windows系统性能翻倍的终极优化指南 【免费下载链接】Winhance-zh_CN A Chinese version of Winhance. C# application designed to optimize and customize your Windows experience. 项目地址: https://gitcode.com/gh_mirrors/wi/Winhanc…

作者头像 李华