C++异常处理

本文详细介绍了C++的异常处理机制,包括抛出异常、栈展开及其过程中对象的销毁、析构函数与异常的关系、异常对象的特性。还讨论了捕获异常的方式,特别是catch-all语句的使用,以及C++11中的noexcept关键字和标准库的exception类层次。此外,文章还提出了异常处理可能带来的问题,如资源泄漏和数据破坏,并探讨了如何确保异常安全,包括不同级别的异常安全保证。
摘要由CSDN通过智能技术生成

C++异常处理

抛出异常

在C++语言中,通过抛出一条表达式来引发一个异常。被抛出的表达式的类型以及当前的调用链共同决定了哪段处理代码将被用来处理该异常。

栈展开

当抛出一个异常后,程序暂停当前函数的执行过程并立即开始寻找与异常匹配的catch子句,如果没找到匹配的catch子句,则继续检查与外层try匹配的catch子句,直到找到了与异常匹配的catch句子为止。如果仍然没有找到匹配的catch子句,则退出当前主调函数,继续在调用当前函数的其他函数中继续寻找。上述这个过程被称为栈展开过程。

栈展开过程沿着嵌套函数的调用链不断查找,直到找到了与异常匹配的catch句子为止,或者也可能一直没找到匹配的catch,则程序将调用标准库函数terminate终止当前的程序,退出主函数后查找过程终止。

栈展开过程中对象被自动销毁

如果在栈展开过程中退出了某个块,编译器将负责确保在这个块中创建的对象能被正确销毁。

如果异常发生在构造函数中,即使某个对象只构造了一部分,我们也要确保已构造的成员能被正确地销毁。(类似的,数组或标准库容器的元素初始化过程中)

析构函数与异常

在栈展开的过程中,运行类类型的局部对象的析构函数。因为这些析构函数是自动执行的,所以它们不应该抛出异常,如果要抛出异常,则应该在析构函数内部得到处理。一旦在栈展开的过程中析构函数抛出了异常,并且析构函数自身没能捕获到该异常,则程序将被终止。

异常对象

异常对象是一种特殊对象,编译器使用异常抛出表达式来对异常对象进行拷贝初始化。因此throw语句中的表达式必须拥有完全类型。

异常对象位于编译器管理的空间中,编译器确保无论最终调用的是哪个catch子句都能访问该空间。

捕获异常

有时候一个单独的catch语句不能完整地处理某个异常,一条catch语句通过重新抛出的操作将异常传递给另外一个catch语句。
很多时候,catch语句会改变其参数的内容。只有当catch异常声明是引用类型时我们对参数所做的改变才会被保留并继续传播:

catch (my_error &eObj) {
   		//引用类型
	eObj.status = errCodes::serverErr;	//修改了异常对象
	throw;
} catch (other_error eObj) {
   		//非引用类型
	eObj.status = errCodes::badErr;
	throw;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值