《Effective C++》第五章:实现
- 尽可能延后变量定义式的出现时间。只有变量在恰好要使用之前定义,程序的可读性往往会得到提高,因为这样不容易忘记变量说代表的意思。另一方面,这样做可以提高程序性能,如果不需要一个变量时却要为它分配、释放空间,调用构造、析构函数,获取、释放资源……这,真是太浪费了。补充一点,声明式并不会做这些事情,所以可以考虑用声明式替换定义式以尽量延后变量的定义。
- 尽量少做转型动作。转型意味着出错的可能性大大提升,转型意味着更多的操作。如果不得不转型,考虑使用C++ style的形式,或提供一个专门的转型函数。
- 避免返回handles指向对象内部成分。引用、指针、迭代器都是指向对象内部成分的handles,返回这些东西就把他们的生杀大权交给了别人,降低了封装性,安全性。如果不得不使用对象内部的成分,考虑返回const型,只让外部具有读取的权利。
- 为”异常安全“而努力是值得的。“异常安全”的代码不泄露任何资源,不允许数据败坏。“异常安全”的代码提供三个保证之一:(1)基本承诺。出现异常时,程序内的任何事物仍然处在有效状态下。没有任何对象或数据结构因此而败坏。(2)强烈保证。操作要么成功,要么不成功。如果操作失败,程序回到操作前的状态。(3)不抛掷保证。不抛出异常。实际情况下,函数内部调用的函数未必提供相应的保证,所以不能总是控制函数具有“异常安全”性,所以,如果全在你的掌控之中,请提供一种异常保证,如果不能,请在文档里说明。
- 透彻了解inlining的里里外外。Inline函数很好,但是过度的inline函数会增加程序的目标码。因为编译器对于inline函数的处理是:对于每个inline函数的调用,都以函数的本体替换之,而不是保存现场,跳转到函数的入口处。Inline函数实现放在头文件里的原因是编译器在编译时就要知道inline函数是什么样子的,以便完成替换。另外一个重点是inline是对编译器的一项建议,是否真正inline由编译器决定。如果要写inline函数,针对那些频繁调用的简单函数。
- 将文件间的编译依存关系降至最低。如果只是修改了程序的一部分,却要重新编译许多不相关的模块,这真是令人焦躁而无语。这主要是由于C++的编译规则引起的,如果A文件里include了B文件,现在只是对A进行修改,那么重新编译时B文件也会被重新编译,而B文件又include了C、D、E文件,而C、D、E文件又……这看起来就是个灾难,所以,非常有必要将文件间的编译依存关系降至最低。至少有三种方式可以做出这样的努力:
1) 能使用object reference 或 object pointer,就不要使用object。reference 或 pointer只需要一个声明式就可以了,不需要定义式。
2) 如果能够,尽量以class声明式替换class定义式。
3) 为声明式和定义式提供不同的头文件,像std那样组织起自己的类。
pimpl idiom手法和abstract base class可以帮助实现上面的方式,并且abstract base class往往意味着多态,而这正是面向对象的思想的体现。23中经典模式里多态还少吗?
时间: 2024-11-03 21:10:33