组织
- 不要拘泥于小节
- 在高警告级别干净利落地进行编译
- 使用自动构建系统
- 适用版本控制系统
- 在代码审查上投入
设计
- 一个实体应该只有一个紧凑的职责
- 正确、简单和清晰第一
- 编程中用该知道何时和如何考虑可伸缩性
- 不要进行不成熟的优化
- 不要进行不成熟的劣化
- 尽量减少全局和共享数据
- 隐藏信息
- 懂得何时和如何进行并发性编程
- 确保资源为对象所拥有。使用显式的 RAII 和智能指针
编程
- 宁要编译时和连接时的错误,也不要运行时错误
- 积极使用 const
- 避免使用宏
- 避免使用“魔数”
- 尽可能局部地声明变量
- 总是初始化变量
- 避免函数过长,避免嵌套过深
- 避免跨编译单元的初始化依赖
- 尽量减少定义性依赖。避免循环依赖
- 头文件应该自给自足
- 总是编写内部 #include 保护符,决不要编写外部 #include 保护符
函数与操作符
- 正确地选择通过值、(智能)指针或者引用传递参数
- 保持重载操作符的自然语义
- 优先使用算术操作符和赋值操作符的标准形式
- 优先使用 ++ 和 -- 的标准形式。优先调用前缀形式
- 考虑重载以避免隐含类型转换
- 避免重载 &&、|| 或 ,(逗号)
- 不要编写依赖于函数参数求值顺序的代码
类的设计与继承
- 弄清所要编写的是那种类
- 用小类代替巨类
- 用组合代替继承
- 避免从并非要设计成基类的类中继承
- 优先提供抽象接口
- 公用继承即可替换性。继承,不是为了重用,而是为了被重用
- 实施安全的改写
- 考虑将虚拟函数声明为非公用的,将公用函数声明为非虚拟的
- 要避免提供隐式转换
- 将数据成员设为私有的,无行为的聚集(C 语言形式的 struct)除外
- 不要公开内部数据
- 明智地使用 Pimpl
- 优先编写非成员非友元函数
- 总是一起提供 new 和 delete
- 如果提供类专门的 new,应该提供所有标准形式(普通、就地和不抛出)
构造、析构与复制
- 以同样的顺序定义和初始化成员变量
- 在构造函数中用初始化代替赋值
- 避免在构造函数和析构函数中调用虚拟函数
- 将基类析构函数设为公用且虚拟的,或者保护且非虚拟的
- 析构函数、释放和交换绝对不能失败
- 一致地进行复制和销毁
- 显式地启用或者禁止复制
- 避免切片。在基类中考虑用克隆代替复制
- 使用赋值的标准形式
- 只要可行,就提供不会失败的 swap (而且要正确地提供)
名字空间与模块
- 将类型及其非成员函数接口置于同一名字空间中
- 应该将类型和函数分别置于不同的名字空间中,除非有意想让它们一起工作
- 不要在头文件中或者 #include 之前编写名字空间 using
- 要避免在不同的模块中分配和释放内存
- 不要在头文件中定义具有链接的实体
- 不要允许异常跨越模块边界传播
- 在模块的接口中使用具有良好可移植性的类型
模板与泛型
- 理智地结合静态多态性和动态多态性
- 有意地进行显式自定义
- 不要特化函数模板
- 不要无意地编写不通用的代码
错误处理与异常
- 广泛地使用断言记录内部假设和不变式
- 建立合理的错误处理策略,并严格遵守
- 区别错误与非错误
- 设计和编写错误安全代码
- 优先使用异常报告错误
- 通过值抛出,通过引用捕获
- 正确地报告、处理和转换错误
- 避免使用异常规范
STL: 容器
- 默认情况下使用 vector。否则选择其它合适的容器。
- 用 vector 和 string 取代数组。
- 使用 vector(以及 string::c_str)来和非 C++ API 交换数据。
- 仅在容器中存储值和智能指针。
- 与其它方法相比,要尽量使用 push_back 来扩大容器。
- 与单元素操作相比,要尽量使用区间操作。
- 使用公认的惯用法来真正地缩小容量以及真正地删除元素。
STL算法(STL: Algorithms)
- 使用一个带检查的(checked)STL 实现。
- 与手工编写的循环相比,要尽量调用 STL 算法。
- 使用正确的 STL 查找算法。
- 使用正确的 STL 排序算法。
- 使 predicate 成为纯函数(pure function)。
- 在用作算法和比较器(comparer)时,要优先用函数对象来代替函数。
- 正确地编写函数对象(Function Object)。
类型安全性(Type Safety)
- 避免类型选择(type switching);尽量使用多态。
- 依赖于对象类型,而不要依赖于对象的表示方法。
- 避免使用 reinterpret_cast。
- 避免用 static_cast 来强制转换指针类型。
- 避免强制去除 const。
- 不要用 C 风格的强制类型转换。
- 不要对非 POD 类型使用 memcpy 或 memcmp。
- 不要用 union 来重新解释数据。
- 不要使用 varargs(省略号)。
- 不要使用无效的对象。不要使用不安全的函数。
- 不要以多态方式处理数组。
网友评论