本文内容基本来自于《Effective C++》一书,为学习后的笔记,以便温故。
《Effective C++ 》第 5 节 实现
(1)条款26:尽可能延后变量定义式的出现时间
(2)条款27:尽量少做转型动作
C++提供了四种新式的转型
A:const_cast通常被用来将对象的常量性转除。它也是唯一有此能力的C++ style转型操作符。
B:dynamic_cast主要用来执行“安全向下转型”,也就是用来决定某些对象是否归属于集成体系中的某个类型。它是唯一无法由旧式语法执行的动作,也是唯一可能耗费重大运行成本的转型动作。
C:reinterpret_cast意图执行低级转型,实际动作可能取决于编译器,这也就表示它并不可移植。
D:static_cast用来强迫隐式转换,例如将non-const对象转换成cosnt对象,或者将int转换成double等等。
请记住:
如果可以,尽量避免转型,特别是在注重效率的代码中避免dynamic_casts,如果有个设计需要转型,试着发展无需转型的替代设计。
如果转型是必要的,试着将它隐藏于某个函数背后。客户随后可以调用该函数,而不需要将转型放入自己的代码中。
宁以C++ style转型,不要使用旧式转型,前者很容易辨识出来,而且也比较有着分别门类的职掌。
(3)条款28:避免返回handles指向对象内部成分
不论这所谓的handle是个指针或者迭代器或者reference,也不论这个handle是否为const,也不论那个返回handle的成员函数是否为const。这里唯一关键的是,有个handle被传出去了,一旦如此你就是暴露在“handle比其所指对象更长寿”的风险下。
(4)条款29:为“异常安全”而努力是值得的
异常安全函数提供以下三个保证之一:
基本承诺:如果异常被抛出,程序内的任何事物仍然保持在有效状态下。没有任何对象或数据结构会因此而败坏,所有对象都处于一种内部前后一致的状态。
强烈保证:如果异常被抛出,程序状态不改变。调用这样的函数需要有这样的认知:如果函数成功,就是完全成功,如果函数失败,程序会恢复到“调用函数之前”的状态。
不抛掷保证:承诺绝不抛出异常,因为他们总能够完成他们原先承诺的功能。作用于内置类型身上的所有操作都提供nothrow保证。
"强烈保证"往往能够以copy-and-swap实现出来,但是“强烈保证”并非对所有函数都可以实现或者具备现实意义。
函数提供的“异常安全保证”通常最高只等于其所调用之各个函数的“异常安全保证”中的最弱者。
(5)条款30:透彻的了街inlining的里里外外
将大多数inlining限制在小型,被频繁调用的函数身上。这可使日后的调式过程和二进制升级更容易,也可使潜在的代码膨胀问题最小化,使程序的速度提升机会最大化。
不要因为funciton templates出现在头文件,就将他们声明为inline
(6)条款31:将文件间的编译依存关系降至最低
Interface classes类似java和.net的interfaces,但是C++的interface classes并不需要负担java和.net的interface所要负担的责任。举个例子:java和.net都不允许在interface内实现成员变量和成员函数,但是C++不禁止这两样东西。C++这种更为巨大的弹性有其用途。
支持“编译依存性最小化”的一般构想是:相依于声明式,不要相依于定义式。基于此构想的两个手段是Handle classes和interface classes
程序库文件应该以“完全且仅有声明式”的形式存在。这种做法不论是否涉及templates都适用。