本篇笔记包含 Term 26~31。
Term 26:尽可能延后变量定义式出现时间
定义一个变量(或者对象)对调用其构造函数,因此最好时在需要的时刻才去定义并初始化。至于只在循环内使用的变量通常定义在循环内,除非明确知道赋值比构造+析构更加高效而且确实有必要时,才将其定义在循环外。
Term 27:尽量少做转型动作
- 如果可以,尽量避免转型,特别是避免低效的 dynamic_casts,优先尝试其它的解决方案
- 如果转型是必要的,试着将它隐藏与函数之中
- 不要使用 C 风格的转型
Term 28:避免返回 handles 指向对象内部成分
避免返回 handles(包括指针、引用、迭代器)指向对象内部成分。这样可以增加封装性,并且避免 handle 在对象被销毁后指向空。
Term 29:为“异常安全”而努力是值得的
- 异常安全函数即使发生异常也不会泄漏资源或允许任何数据结构破坏
- 异常安全函数三种保证:基本型(保证程序有效)、强烈型(保证程序回到之前的状态)、不抛异常型
- 强烈保证往往能够以 copy-and-swap 实现出来,但强烈保证并非对所有函数都可以实现或具备现实意义
- 函数提供的异常安全保证通常等于其所调用的函数中异常安全保证最弱的那个(木桶效应)
Term 30:透彻了解 inlining 的里里外外
inline 是编译器可选的操作,实际取决于具体编译器的平台和版本等。
- 定义于 class 内的函数是一种隐式 inline 请求
- inline 应当用于小型的、调用频繁的函数,避免代码膨胀,使调试和程序升级的过程也变得更加容易
Term 31:将文件间的编译依存关系降至最低
降低文件间的编译依存关系有助于减少编译的工作量
- 支持“编译依存性最小化”的一般构想是:相依与声明式,不要相依于定义式。基于此构想的两个手段是 Handle classes 和 Interface classes
- 程序库头文件应该以“完全且仅有声明式”的形式存在