C++笔记——c++编程思想(下)第一章异常处理

1. 传统的C中处理错误的方法有三种:(1)使用全局状态本标记来标识异常状态,或是函数返回值区别错误类型;(2)使用鲜为人知的C中的signal和raise库函数提供的信号处理系统;(3)使用C库中的非局部跳转函数:setjmp()和longjmp(),这种非局部跳转函数与goto的区别是:goto只在一个函数中进行跳转。这些方法的缺点在于,信息不丰富,各种错误信号要定义,对应关系及其含义很烦琐,不系统,而且方法(3)还不能调用析构函数,故在C++中不适用,因而引用了异常机制。

2. C++中的异常可以是任何类型(Java中只能是Exception的子类);但最好设计特定的异常类。异常抛出后,等于将函数返回值类型设成了所抛对象的类型,但与return不同的是,异常抛出后返回的地方是异常处理器(catch模块),而非函数调用的后续语句,此外,异常发生之前定义的局部对象将被销毁,这种行为称为栈反解(stack unwinding)。

3. catch匹配时,支持向上转型,但不支持自动类型转换,最好不用值捕获而用引用,避免切片。

4. catch(...)捕获所有异常,重新抛出异常用throw;重新抛出异常会将异常传递给更高一级的异常处理器。

5. 所有层次的异常处理器都未作出处理的异常,会到最外层调用terminate函数。它默认调用C库函数abort,使程序执行异常中止而退出,执行abort时,全局对象和静态对象的析构函数不会被调用。

6. 通过标准的set-terminate函数可以设置自己的terminate函数,该方法返回被替换的terminate函数的指针,以备恢复时用。

7. 在下面两种情况下terminate函数也会被执行:(1)局部对象的析构函数抛出异常时,正在进行栈返解(处理异常时再抛新异常);(2)全局或静态对象的构造或析构函数抛出一个异常(因为无法定义catch块),故一般不是构造和析构函数中抛出异常。

8. 为防止构造函数中抛出异常,导致析构函数未被调用,而已分配的空间无法释放,方法有二:在方法内捕获并处理异常,释放空间;(2)以及使用智能指针释放资源。

9. 异常规格说明:

void f();//可抛出任何异常

void f() throw();//不抛出任何异常

void f() throw(tosmall,tobig,divzero)//可抛出三种异常

10. 如果异常规格说明中未包含所抛出的异常,则会引发一个unexpected函数,它会调用前面提到的terminate方法。同样可以用set-unexpected设置自定义的unexpected方法。

11. unexpected方法可以抛出一个异常,如果该异常匹配,则catch块工作,否则下面情形之一将会发生:

(1)如果异常规格说明中包括std::bad_exception则unexpected会抛出一个bad_exception,然后重新匹配各块catch

(2)否则执行terminate

12. 异常规格说明主要用于非模板类,模板无法确定有哪些异常类。

  • 2
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值