东阳的学习记录
条款26:尽可能延后变量定义式的出现时间
- 程序控制流到达这个变量定义式时,需承担构造成本,离开作用域时,承担析构成本
- 避免定义 “不使用的变量”。
- 尽可能延后,直到非得到使用前才定义,甚至应该尝试延后这份定义直到能够给他初始实参为止。
条款27:尽可能少做转型动作
- 转型在继承体系中表现为,有一个偏移量(offset)在运行期被施加到了 Derived* 指针上。
- 在继承体系中对派生类进行强转为base,会生成一个 “*this对象之base class”副本,这样做会导致原对象的base部分并未成功更改,这样做是危险的。
- dynamic_cast的执行效率非常低,在注重效率的代码中慎用
- 必须避免的是连续使用一连串的dynamic_cast。
- 在不得不使用转型时,隔离转型动作,将其隐藏在某个函数中
- 宁可使用新式转型,不要使用旧式转型。前者容易辨别。
条款28:避免返回handles指向对象内部成分(这会破环封装)
- 即使声明为const,仍然有风险,比如出现空悬的“号码牌”
- 总之避免返回handles指向对象内部成分。
条款29:为“异常安全”而努力是值得的
- 异常安全的指:i. 不泄漏任何资源 ii. 不允许数据败坏
- 基本承诺:原子性:始终保持一致性状态;强烈承诺:在基本承诺之上,如果调用失败,会回到没调用之前的状态
- 在函数执行完毕之后才改变状态信息。
- 强烈保证有时候不切实际,比如步骤很多并且操纵全局信息时,此时只需要保证基本承诺
条款30:透彻了解inlining的里里外外
- inline会使得程序的体积膨胀
- inline 只是像编译器提出申请
- inline 函数通常一定被放置于头文件类,编译器必须要知道其具体实现,才能内联
- inline在大多数C++程序中时编译期行为
- templates通常也被置于头文件内,编译器将其具现化时需要知道它具体实现
- virtual 函数无法inline
- 使用函数指针调用时,不会执行inline
- 构造函数和析构函数不适合inline。构造函数和析构函数并不像我们看到的那样小巧,编译器会对其进行处理。
- inline函数无法随着程序的升级而升级,一旦改变内联函数,必须重新进行编译。
- 调试过程中,大多数建置环境只能禁止inline
- 80-20法则
条款31:将文件间的编译依存降到最低
- 前置声明每一件东西,编译器必须在编译期知道被声明的对象的大小
- 当分离式编译导致的速度和或大小差异过于重大以至于 class 之间的耦合相比较之下不成为关键时,就以具像类替换 handle classes 和 interface classes。
- 程序库头文件应该以 “完全且仅有声明式”形式存在,不管是否涉及 templates 都适用(尽量)