[2] C 和C++的公共子集并不是学习C++时最好的开始子集。
p> [3] 对于产品代码,请记住并不是每个C++实现都是完全的最新的。在产品代码中使用某个新特征之前应先做试验,写一个小程序,测试你计划使用的实现与标准的相符情况和性能。[4] 避免被贬斥的特征,例如全局的static;还应避免C 风格的强制。
[5]"隐含的int"已禁止,因此请明确描述每个函数、变量、const 等的类型。
[6] 在将C 程序转为C++程序时,首先保证函数声明(原型)和标准头文件的一致使用。
[7] 在将C 程序转为C++程序时,对以C++关键字为名的变量重新命名。
[8] 在将C 程序转为C++程序时,将malloc()的结果强制到适当类型,或者将malloc()的所有使用都改为new。
[9] 在将malloc()和free()转为new 和delete 时,请考虑用vector、push_back()和reserve()而不是realloc()。
[10] 在将C 程序转为C++程序时,记住这里没有从int 到枚举的隐式转换;如果需要,请用显式转换。
[11] 在名字空间std 里定义的功能都定义在无后缀的头文件里(例如,std::cout 声明在里)。早些的实现将标准库功能定义在全局空间里,声明在带.h 后缀的头文件里(例如,std::cout声明在里)。
[12] 如果老的代码检测new 的结果是否为0,那么必须将它修改为捕捉bad_alloc 或者使用new(nothrow)。
[13] 如果你用的实现不支持默认模板参数,请显式提供参数;用typedef 可以避免重复写模板参数(类似于string 的typedef 使你无须写basic_string, allocator >)。
[14] 用得到std::string(里保存的是C 风格的串函数)。
[15] 对每个标准C 头文件,它将名字放入全局名字空间;与之对应的头文件将名字放入名字空间std。
[16] 许多系统有一个"String.h"头文件里定义了一个串类型。注意,这个串类型与标准库的string 不同。
[17] 尽可能使用标准库功能,而不是非标准的功能。
[18] 在声明C 函数时用extern "C"。
附录C
[1] 应集中关注软件开发而不是技术细节。
[2] 坚持标准并不能保证可移植性。
[3] 避免无定义行为(包括专有的扩充)。
[4] 将那些实现定义的行为局部化。
[5] 在没有{、}、[、]、|或!的系统里用关键字和二联符表示程序,在没有\的地方用三联符。
[6] 为了方便通信,用ASCII 字符去表示程序。
[7] 采用符号转义字符比用数值表示字符更好些。
[8] 不要依赖于char 的有符号或者无符号性质。
[9] 如果对整数文字量的类型感到有疑问,请使用后缀。
[10] 避免破坏值的隐式转换。
[11] 用vector 比数组好。
[12] 避免union。
[13] 用位域表示外部确定的布局。
[14] 注意不同存储管理风格间的权衡。
[15] 不要污染全局名字空间。
[16] 在需要作用域(模块)而不是类型的地方,用namespace 比class 更合适。
[17] 记住static 类成员需要定义。
[18] 用typename 消除对模板参数中类型成员的歧义性。
[19] 在需要用模板参数显式限定之处,用template 消除模板类成员的歧义性。
[20] 写模板定义时,应尽可能减少对实例化环境的依赖性。
[21] 如果模板实例化花的时间过长,请考虑显式实例化。
[22] 如果需要编译顺序的显式可预见性,请考虑显式实例化。
附录D
[1] 应预期每个直接与人打交道的非平凡程序或者系统都会用在多个国家。
[2] 不要假定每个人使用的都是你所用的字符集。
[3] 最好是用locale 而不是写实质性代码去做对文化敏感的I/O。
[4] 避免将现场名字字符串嵌入到程序正文里。
[5] 尽可能减少全局格式信息的使用。
[6] 最好是用与现场有关的字符串比较和排序。
[7] 保存facet 的不变性。
[8] 应保证改变现场的情况只出现在程序里的几个地方。
[9] 利用现场去管理刻面的生存期。
[10] 在写对现场敏感的I/O 函数时,记住去处理用户(通过覆盖)提供的函数所抛出的异常。
[11] 用简单的Money 类型保存货币值。
[12] 要做对现场敏感的I / O,最好是用简单的用户定义类型保存所需的值(而不是从内部类型的值强制转换)。
[13] 在你对涉及到的所有因素有了很好的看法之前,不要相信计时结果。
[14] 当心time_t 的取值范围。
[15] 使用能接受多种输入格式的日期输入例程。
[16] 最好采用那些明显表明了所用现场的字符分类函数。
附录E
[1] 弄清楚你想要什么级别的异常时安全性。
[2] 异常时安全性应该是整体容错策略的一部分。
[3] 为所有的类提供基本保证,也就是说,维持一个不变式,而且不流失资源。
[4] 在可能和可以负担之处提供强保证,使操作或者成功,或者保持所有操作对象不变。
[5] 不要从析构函数里抛出异常。
[6] 不要从一个遍历合法序列的迭代器里抛出异常。
[7] 异常时安全性涉及到仔细检查各个操作。
[8] 将模板设计为对异常透明的。
[9] 更应该用申请资源的构造函数方式,不要采用init()函数。
[10] 为类定义一个不变式,使什么是合法状态变得非常清晰。
[11] 确保总将对象放在合法状态中,也不要怕抛出异常。
[12] 保持不变式简单。
[13] 在抛出异常之前,让所有操作对象都处于合法状态。
[14] 避免资源流失。
[15] 直接表示资源。
[16] 记住swap()有时可以成为复制元素的替代方式。
[17] 在可能时依靠操作的顺序,而不是显式地使用try 块。
[18] 在替代物已经安全生成之前不销毁"老"信息。
[19] 依靠"资源申请即初始化"技术。
[20] 确保关联容器的比较操作能够复制。
[21] 标明关键性数据结构,并为它们定义能够提供强保证的操作。