异常

https://github.com/Mq-b/CppLab/blob/main/md/C%2B%2B异常.md
除非是极端性能敏感场景,否则大多情况优先使用异常。
异常能够自动传播错误,将错误处理代码从主逻辑中移出,进行跨函数的控制流处理,无需在每个函数中反复检查返回值并传递错误状态。
常见适用异常处理错误:下标越界、算术溢出、参数不合法、内存分配不足
不适用于:处理异步事件,如磁盘读写结束、网络信息到达、点击鼠标键盘

异常处理思想:
![[Pasted image 20250804134507.png]]

异常处理方法:
抛掷异常的程序段

throw 表达式

函数中throw之后的部分都不会执行
捕获处理异常

try
	复合语句//保护段,可能抛出异常,catch捕获
catch(异常对象)
	复合语句//异常处理程序
catch(...){}//优先捕获规定的异常类型,其次是这个

异常声明(异常规范)

可在函数声明中列出函数可以抛掷的所有异常类型
如void func() throw(A,B,C,D)。ABCD是变量类型
若不声明异常接口,函数可抛所有类型异常

  • 保证不抛异常:
void func() noexcept;//
void func() throw(

);
void func() noexcept(noexcept(funcA()));//如果noexcept(funcA())结果为true则不会抛出异常,即看funcA()是否会抛出异常。

若声明为noexcept的函数内部抛出了异常,程序会直接调用std::terminate()
实际开发中,应该适用标准的异常对象。如果用户想定义异常类型,通常需要继承标准异常类,如std::exception,简单需求时重写what虚函数

RAII

'”资源获取即初始化“ ' (Resource Acquisition Is initialization)
构造函数申请资源、析构函数释放资源、异常抛出时调用对象析构函数,保证资源不泄露。

  • RAII=资源生命周期绑定对象+异常安全保证

如果异常被抛出但没有被捕获,则会调用std::terminate终止程序。是否对未捕获的异常进行栈回溯由实现定义。

  • 栈回溯就是在执行函数过程中遇到异常,函数按构造的逆序清理局部对象并返回的过程

异常安全

四个被广泛认可的异常保证等级,每个是另一个的严格超集
1.不抛出(不失败)异常保证
2.强异常保证——如果抛出,则程序恰好回到函数调用前的状态
3.基本异常保证——如果抛出,则程序处于某个有效状态,不会泄露资源
4.无异常保证——可能发生资源泄漏、内存损坏

posted @ 2025-08-05 11:04  Los1r  阅读(10)  评论(0)    收藏  举报