实现
谨记 80 - 20 原则
谨记条款 13: 以对象管理资源
条款26
尽可能延后变量定义式的出现时间
尽可能延后变量定义式的出现,这样可增加程序的清晰度并改善程序效率.
条款27
尽量少做转型动作
如果可以,尽量避免转型,特别在注重效率的代码中避免dynamic_cast,尝试以无需转型的方案替代需要转型的方案设计.
若转型是必要的,试着将其隐藏在某个函数背后,客户无需将转型代码放到自己的代码中.
要用C++ style转型,不压使用C style转型.
条款28
避免返回handles指向对象内部成分
此处的handle可以是指针,引用,迭代器.
避免返回handles指向对象内部,帮助const成员函数的行为像个cons,并将"虚的handle"的可能性降到最低.
条款29
为"异常安全"而努力是值得的
异常安全函数(exception-asfe functions)表示即使发生异常也不会泄露资源或允许任何数据结构破坏. 可提供三种保证之一:
- 基本承诺; 2. 强烈保证, 程序状态恢复到异常安全函数调用之前; 3. 不抛掷保证. 承诺不抛掷异常.
"强烈保证"往往能够以 copy-and-swap 实现出来, 但"强烈保证"往往不具现实意义.
函数提供的"异常安全保证"通常最高只等于所调用各个函数的"异常安全保证"中的最弱者.
copy-and-swap原则: 为打算改变的对象(原件)做出一份副本, 然后在那副本身上做一切需要的修改, 若修改动作发生任何异常, 原对象仍保持未改变的状态. 待所有修改发生后, 再将修改过的副本与原件进行swap. 实现上通常是将"隶属对象的数据"从原对象放入另一个对象内, 然后赋予原对象一个指针, 指向那个所谓的实现对象(副本), 这种手法被称作 pimpl idiom. 注意, 这里会增加一层封装.
条款30
透彻了解 inlining 的里里外外
inine 的态度: 对此函数的每次调用, 都置换成函数本体.
inline 的两种实现方式: 显示声明, 隐喻(函数定义在class定义内)
将大多数inlining限制在小型, 被频繁调用的函数身上. 这可使日后的调试过程和二进制升级更容易, 也可使潜在的代码膨胀问题降到最小, 使程序的速度提升机会最大化.
不要只因为 function template 出现在头文件, 就将它们声明为 inline. 若你觉得所有根据此 template 具象出来的函数都应是 inline 的, 才应将此 tenplate 声明为 inline.
条款31
将文件间的编译依存关系降至最低
支持"编译依存性最小化"的一般构想是: 相依于声明式, 不要相依于定义式. 基于此构想的两个手段是 handle classes 和 interface classes.
程序库头文件应"完全且仅含有声明式"的形式存在, 这种做法不论在是否涉及template都适用.
handle class 采用了 pimpl idiom 方法, 即 class 中存在一个指针成员(或非指针成员)指向该 class 的实现 class(pImpl). class 所有方法的实现都通过其实现类完成.
interface class 是指一个描述 class 的接口, 通常不含有成员变量, 也没有构造函数, 只有一个 virtual 析构函数, 和一组 pure virtual 函数, 用来描述整个接口. 类似于 Java 中的 Interface, 但存在一些差异. 对于 interface class 的使用, 首先, 必须要有一个具象 class, 通常在 interface 中声明一个 static create 函数, 用于创建新对象, 即充当构造函数的任务.