C++ primer 第十七章 异常处理部分

1.      异常处理的意义:将问题的检测和解决分离,这样问题检测部分可以不必了解如何处理问题。

2.      异常是通过抛出对象而引发的,被选中的处理代码是调用链中与该对象类型匹配而且离抛出位置最近的代码。

3.      异常是可以传给非引用形参的任意类型的对象,这意味着必须能复制该类型的对象。

4.      执行throw的时候,不会执行在throw后的语句,而是将控制权从throw转移到catch,catch可以使同一函数中局部的catch,也可以在直接或间接调用发生异常的函数的另一个函数中。

5.      在处理异常的时候,抛出异常的块中的局部存储不存在了。被抛出的对象,用throw表达式初始化一个称为异常对象的特殊对象,由编译器管理,保存在可能被激活的任意catch都可以访问的空间。异常完全处理之后,撤销该对象。

6.      抛出指向局部对象的指针是错误的,跟从函数返回指向局部对象的指针一样。

7.      栈展开:抛出异常后,暂停当前函数的执行,开始查找匹配的catch函数。首先检查throw是否在try内部,如果是,则检查与该try相关的catch,看是否其中有与被抛出对象相匹配。如果找到,就处理;如果没有,就退出当前函数,并继续在调用函数中查找。沿函数调用链继续向上,直至找到一个catch语句。

8.      如果一个块直接分配资源(new),在释放资源之前发生异常,在栈展开期间将不会释放该资源。

9.      析构函数不应该抛出异常,如果又抛出自己的未经处理的另一个异常,将会导致调用标准库terminate函数。一般来说,terminate函数将调用about函数,强制从整个函数非正常退出。

10.  另外,不能不处理异常。如果找不到匹配的catch,就调用terminate函数。

11.  在查找catch期间,找到的catch不必是最匹配的那个,而是第一个可以处理该异常的catch。所以,在catch子句列表中,最特殊的catch必须最先出现。

12.  除去下面三种情况,异常类型必须与catch说明完全匹配:

·允许从非const到const的转换

·允许从派生类到基类类型的转换

·将数组转换为指向数组类型的指针

13.  重新抛出:catch将异常传递给调用链中更上层的函数。方法是,在catch或者catch调用的函数中写空throw;语句。

14.  捕获所有异常的catch句:catch(…){ }

15.  函数测试块:可以使用函数测试块try{}将一组catch子句与函数连成一个整体。为了处理来自构造函数初始化的异常,必须将构造函数编写成测试块。

16.  资源分配即初始化RAII,通过定义一个类来封装资源的分配和释放,可以保证正确释放资源,如auto_ptr类。

17.  异常说明,跟在函数形参表之后的throw(异常列表)。throw()空列表表示不抛出任何异常。如果没有指定异常说明,则可抛出任意类型的异常。

18.  如果函数跑出了没有在异常说明中列出的异常,会调用标准库函数unexpected,默认情况下,unexpected调用terminate函数。

19.  在const成员函数声明中,异常说明跟在const之后。

const char* what() const throw();

20.  基类中虚函数的异常说明,可以与派生类中对应虚函数的异常说明不一样。但是,派生类虚函数的异常说明必须至少与其基类虚函数的异常说明同样严格,或者更严格。这样可保证,在基类指针调用派生类虚函数的时候,派生类的异常说明不会增加新的可抛出异常。

21.  异常说明是函数类型的一部分,这样,可以在函数指针的定义中提供异常说明

void (*pf) (int) throw (runtime_error);

如果用另一指针pf2初始化函数指针pf1,则pf2的异常说明要至少与pf1一样严格。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章