C++ Coding Standards: 101 Rules, Guidelines, and Best Practices

基本信息

  • 作者: Herb Sutter, Andrei Alexandrescu
  • 原书名: C++ Coding Standards: 101 Rules, Guidelines, and Best Practices
  • 文件大小: 1.99 MB
  • 页数: 279页
  • 类型: 文本型PDF

核心观点

本书是C++编码规范的权威指南,由C++标准委员会核心成员Herb Sutter和泛型编程大师Andrei Alexandrescu合著。全书101条准则按主题分类,每条准则都有清晰的理由说明和示例。

核心原则

  1. 正确性、简单性和清晰性优先 — 不要过早优化,先让代码正确、可读
  2. 在编译期而非运行期捕获错误 — 利用模板、常量表达式、static_assert等
  3. 资源由对象管理,使用RAII和智能指针 — 避免手动内存管理
  4. 隐藏信息,减少耦合 — 封装、最小化全局状态、避免循环依赖
  5. 代码审查是最佳投资 — 相比自动化工具,人工审查发现更多问题

章节结构

第一部分:组织和政策问题(第0-4章)

  • 第0章: 不要纠结小事 — 知道什么不该标准化
  • 第1章: 在高警告级别下干净编译
  • 第2章: 使用自动化构建系统
  • 第3章: 使用版本控制系统
  • 第4章: 投入代码审查

第二部分:设计风格(第5-13章)

  • 第5章: 给实体一个内聚的责任(单一职责)
  • 第6章: 正确性、简单性、清晰性优先
  • 第7章: 何时以及如何为可扩展性编码
  • 第8章: 不要过早优化
  • 第9章: 不要过早 pessimize
  • 第10章: 最小化全局和共享数据
  • 第11章: 隐藏信息
  • 第12章: 何时以及如何为并发编码
  • 第13章: 确保资源由对象拥有,使用显式RAII和智能指针

第三部分:编码风格(第14-24章)

  • 第14章: 优先编译期和链接期错误
  • 第15章: 主动使用const
  • 第16章: 避免宏
  • 第17章: 避免魔术数字
  • 第18章: 尽可能局部声明变量
  • 第19章: 始终初始化变量
  • 第20章: 避免长函数和深层嵌套
  • 第21章: 避免跨编译单元的初始化依赖
  • 第22章: 最小化定义依赖,避免循环依赖
  • 第23章: 让头文件自足
  • 第24章: 始终写内部#include守卫

第四部分:函数和运算符(第25-27章)

  • 第25章: 适当按值、(智能)指针或引用传递参数
  • 第26章: 保持重载运算符的自然语义
  • 第27章: 优先算术和赋值运算符的标准形式

第五部分:异常处理(第28-32章)

  • 第28章: 用异常报告错误
  • 第29章: 用断言检查不变量
  • 第30章: 用预处理条件保护不变量
  • 第31章: 用后置条件保证结果
  • 第32章: 理解并使用异常规范

第六部分:模板(第33-37章)

  • 第33章: 用模板避免重复代码
  • 第34章: 优先用模板特化而非if-else链
  • 第35章: 避免模板元编程的陷阱
  • 第36章: 理解模板实例化时机
  • 第37章: 使用SFINAE进行编译期分发

第七部分:STL使用(第38-43章)

  • 第38章: 优先用算法而非手写循环
  • 第39章: 选择正确的容器
  • 第40章: 使用迭代器而非索引
  • 第41章: 理解容器的性能特征
  • 第42章: 使用算法的正确形式
  • 第43章: 避免STL的常见陷阱

第八部分:互操作性(第44-46章)

  • 第44章: 与C代码互操作
  • 第45章: 处理遗留代码
  • 第46章: 模块化和接口设计

第九部分:性能(第47-50章)

  • 第47章: 测量而非猜测
  • 第48章: 优化算法复杂度
  • 第49章: 缓存友好性
  • 第50章: 避免微优化

关键准则摘录

第6章:正确性、简单性、清晰性优先

  • 代码首先要是正确的,然后是简单的,最后是清晰的
  • 复杂度是bug的温床
  • “Make it right, then make it fast, but not before”

第8章:不要过早优化

  • 度量是优化之父
  • 大多数优化应该通过选择更好的算法完成,而非微优化
  • 过早优化是万恶之源(Knuth)

第10章:最小化全局和共享数据

  • 全局状态是并发问题的根源
  • 共享可变状态需要锁定,锁定带来死锁风险
  • 优先使用局部变量和值语义

第11章:隐藏信息

  • 封装减少耦合
  • 公有接口应最小化
  • 实现细节应隐藏在私有部分或Pimpl中

第13章:RAII和智能指针

  • 资源获取即初始化 — 构造函数获取资源,析构函数释放
  • 优先使用unique_ptr、shared_ptr、weak_ptr
  • 避免裸new/delete

与其他知识的关联

可行动点

  1. 在项目中使用高警告级别编译(-Wall -Wextra -Werror)
  2. 引入代码审查流程
  3. 用智能指针替代裸指针
  4. 用std::array/vector替代C风格数组
  5. 用constexpr替代宏常量
  6. 避免跨编译单元的静态对象初始化依赖

备注

  • 本书出版于2004年,部分内容针对C++98/03,但核心理念适用于C++11及以后
  • 建议配合现代C++指南(如cppreference.com)一起学习
  • 101条准则可按需选用,不必每条都严格遵守