C++ Primer 中文版 学习笔记(十六)

第17章   用于大型程序的工具

1        大规模应用程序往往具有下列特殊要求:

  1. 更严格的正常运转时间以及更健壮的错误检测和错误处理。错误处理经常必须跨越独立开发的多个子系统进行。        ----异常处理,错误检测与处理分开
  2. 能够用各种库(可能包含独立开发的库)构造程序。                   ----命名空间
  3. 能够处理更复杂的应用概念。                                                                                                                         ----多重继承

2        异常以类似于将实参传递给函数的方式抛出和捕获,必须能够复制该类型的对象,因此不存在数组或函数类型的异常

3        将控制从throw转移到匹配的catch,有两个重要的含义

  1. 沿着调用链的函数提早退出。
  2.  一般而言,在处理异常的时候,抛出异常的块中的局部存储不存在了。

4        当抛出一个表达式的时候,被抛出对象的静态编译时类型将决定异常对象的类型

  1. 在抛出中对指针解引用,无论对象的实际类型是什么,异常对象的类型都与指针的静态类型相匹配。
  2. 抛出局部对象的指针总是错误的。
  3. 抛出指针的时候,必须确定进入处理代码时指针所指向的对象存在。

5        栈展开:沿嵌套函数调用链继续向上,直至为异常找到一个catch子句。

6        栈展开期间,释放局部对象所用的内存并运行类类型局部对象的析构函数,通常编译器不撤销内置类型的对象。
7        析构函数应该从不抛出异常:

             在为某个异常进行栈展开的时候,析构函数如果又抛出自己的未经处理的另一个异常,将会导致调用标准库terminate函数,terminate函数调用abort函数,强制从这个                程序非正常退出。

8        catch中的异常说明符的静态类型决定catch子句可以执行的动作。
9        带有因继承而相关的类型的多个catch子句,必须从最低派生类型到最高派生类型排序

try{
//use of the c++ standard library
}catch(overflow_erroreobj){
//…
}catch(construtime_error &re){
//…
}catch(exception){/*…*/}

10     new 和 delete之间若发生异常将导致动态分配的内存未被释放。所以我们需要异常安全的编程方法,即RAII(Resource Allocate Is Initialization).通过定义一个类来封装资源的分配和释放。(析构函数自动运行)。
11     RAII 的一个例子就是 auto_ptr类:

要正确的使用auto_ptr类,必须坚持该类强加的下列限制:

  1. 不要使用auto_ptr对象保存指向静态分配对象的指针,会导致撤销时产生未定义行为。
  2. 永远不要使用两个auto_ptr对象指向同一对象
  3. 不要使用auto_ptr对象保存指向动态分配数组的指针,撤销时只释放一个对象delete 而不是delete[]
  4. 不要讲auto_ptr对象存储在容器中。auto_ptr对象的复制和赋值具有破坏性。在复制(或者赋值)auto_ptr对象之后,原auto_ptr对象不指向对象而新的auto_ptr对象(左操作数)拥有基础对象。

12     若函数有形如throw()的异常说明:不抛出任何异常  若没有异常说明:可抛出任意类型异常
13     Using声明 using指示(尽量避免)
14     多重继承构造函数调用次序既不受构造函数初始化列表中出现的基类的影响,也不受基类在构造函数初始化列表中的出现次序的影响。
15     为解决多重继承多个基类可能导致出现的二义性问题,引出虚继承。

          在虚继承下,对给定虚基类,无论该类在派生层次中作为虚基类出现多少次,只继承一个共享的基类子对象。                                                

           为避免重复初始化问题:规定由最低层派生类的构造函数初始化虚基类。

16  无论虚基类出现在继承层次中任何地方,总是在构造非虚基类之前构造虚基类。

没有更多推荐了,返回首页