5 实现
大多数情况下,适当提出拟的类定义以及函数声明,是花费最多心力的两件事。尽管如此,还是有很多东西需要小心:太快定义变量可能造成效率上的拖延;过度使用转型(casts)可能导致代码变慢又难维护,又招来微妙难解的错误;返回对象“内部数据之号码牌(handls)”可能会破坏封装并留给客户虚吊号码牌;为考虑异常带来的冲击则可能导致资源泄漏和数据败坏;过度热心地inlining可能引起代码膨胀;过度耦合则可能导致让人不满意的冗长建置时间。
条款26:尽可能延后变量定义式的出现时间
Postpone variable definitionsas long as possible
“通过默认构造函数构造出一个对象然后对它赋值”比“直接在构造函数时制定初值”效率差。
“尽可能延后”的真正意义应该是:你不只应该延后变量的定义,直到非得使用该变量的前一刻为止,甚至应该尝试延后这份定义直到能够给它初值实参为止。
– 做法A: 1个构造函数 + 1 个析构函数+ n 个赋值操作
– 做法B: n个构造函数 + n 个析构函数
※
尽可能延后变量定义式的出现。这样做可增加程序的清晰度并改善程序效率。
条款27:尽量少做转型动作
Minimize casting.
– Const_cast 通常被用来将对象的常量性转除(cast away the constness)。
– Dynamic_cast用来执行“安全向下转型”,用来决定某对象是否归属继承体系中的某个类型。
– Reinterpret_cast执行低级转型,取决于编译器,表示它不可移植。
– Static_cast 强迫隐式转换。
※
l 如果可以尽量避免转型。
l 如果转型是必要的,试着将它隐藏于某个函数背后。
l 宁可使用C++style(新式)转型,不要使用旧式转型。
条款28:避免返回handles指向对象内部成员
Avoid returning “handles”to object internals.
※
避免返回handles(包括reference 、指针、迭代器)指向对象内部。遵守这个条款可增加封装性,帮助const成员函数的行为像个const,并将发生“虚吊号码牌”(danglinghandles)的可能性降至最低。
条款29:为“异常安全”而努力是值得的
Strive for exception-safe code.
异常安全:
1. 不泄露任何资源
2. 不允许数据败坏
※
- 异常安全函数(exception-safe functions)即使发生异常也不会泄露资源或允许任何数据结构败坏。这样的函数区分为三种可能的保证:基本型、强烈型、不抛异常型。
- “强烈保证”往往能够以copy-and-swap实现出来,但“强烈保证”并非对所有函数都可实现或具备现实意义。
- 函数提供的“异常安全保证”通常最高只等于其所调用之各个函数的“异常安全保证”中的最弱者。
条款30:透彻了解inlining的里里外外
Understand the ins and outs of inlining.
代码膨胀会导致额外的换页行为,降低指令高速缓存装置的击中率,以及伴随着效率的损失。
※
- 将大多数inlining限制在小型、被频繁调用的函数上。这可使日后的调试过程和二进制升级(binary upgradability)更容易,也可使潜在的代码膨胀问题最小化,使程序的速度提升机会最大化。
- 不要只因为function templates出现在头文件,就将它们声明为inline。
条款31:将文件的编译依赖关系降至最低
Minimize compilation dependencies between files.
编译器必须在编译期间知道对象的大小
- 支持“编译依存性最小化”的一般构想是:相依于声明式,不要相依于定义式。基于此构想的两个手段是Handle classes和Interface classes。
- 程序库头文件应该以“完全且仅有声明式”(full and declearation-only forms)的形式存在。这种做法不论是否涉及templates都适用。

本文探讨了C++编程中的五大关键原则:延迟变量定义以提高效率、减少类型转换以增强安全性、避免返回对象内部句柄以确保封装性、追求异常安全性以防止资源泄漏和数据损坏、理解内联机制以优化性能。
1543

被折叠的 条评论
为什么被折叠?



