C++ Coding Standards: 101条规则、指南与最佳实践
基本信息
- 书名:C++ Coding Standards: 101 Rules, Guidelines, and Best Practices
- 作者:Herb Sutter, Andrei Alexandrescu
- 页数:279页
- 文件大小:1.99MB
- 原书路径:/books/c++/Cpp_Coding_Standards/C++_Coding_Standards.pdf
书籍概述
本书由C++标准委员会核心成员Herb Sutter和泛型编程大师Andrei Alexandrescu合著,提出了101条C++编码规范,是C++编程实践中最实用的规范参考书。不同于语言规范层面的”应该做什么”,本书聚焦于”如何做才对”,覆盖从编译配置到代码审查的全流程。
全书分为五大主题:组织与策略问题、设计风格、编码风格、函数与运算符、异常处理与资源管理。
核心规则摘要
一、组织与策略问题
规则0:不要纠结细节(知道什么不该标准化)
- 不是所有东西都需要标准;有些属于个人偏好
- 团队先就核心原则达成一致,细节可以灵活
规则1:以高警告级别干净编译
- 开启所有警告并视为错误(-Wall -Werror)
- 编译失败比运行失败好得多
规则2:使用自动化构建系统
- Make/CMake等工具确保构建可重复
规则3:使用版本控制系统
- Git等工具追踪变更历史
规则4:投入代码审查
- 代码审查是发现bug最有效的手段之一
- 重点审查设计逻辑,而非格式
二、设计风格
规则5:一个实体承担一个 cohesive 职责
- 单一职责原则:每个类/函数只做一件事
- 避免职责混杂导致的复杂性
规则6:正确性、简单性和清晰度优先
- 正确 > 简单 > 清晰 > 快
- 不要为了优化而牺牲可读性
规则7:知道何时以及如何为可扩展性编码
- 为变化做准备,但不要过度设计
- YAGNI原则:不要过早抽象
规则8:不要过早优化
- 先测量,再优化
- 优化必须基于数据而非猜测
规则9:不要过早劣化
- 避免不必要的复杂性
- 保持代码简洁比追求通用更重要
规则10:最小化全局和共享数据
- 全局变量是并发和难以推理的根源
- 优先使用局部变量和对象封装
规则11:隐藏信息
- 尽可能减少可见性
- private > protected > public
规则12:知道何时以及如何为并发编码
- 线程安全是可选特性,不是默认行为
- 使用RAII管理锁
规则13:确保资源由对象拥有,使用显式RAII和智能指针
- RAII是C++资源管理的基石
- 优先使用unique_ptr/shared_ptr而非裸指针
三、编码风格
规则14:优先编译/链接时错误而非运行时错误
- 能用static_assert就用
- 类型检查比运行时断言更好
规则15:主动使用const
- const是接口契约的一部分
- const正确性可以防止意外修改
规则16:避免宏
- 宏没有类型安全,无法调试
- 用inline函数、template、enum替代
规则17:避免魔术数字
- 用命名常量替代字面量
- 提高可读性和可维护性
规则18:尽可能局部声明变量
- 变量应在首次使用前声明
- 减少作用域,提高可读性
规则19:总是初始化变量
- 未初始化变量是bug的来源
- 用列表初始化确保初始化
规则20:避免长函数,避免深层嵌套
- 函数应简短 focused
- 嵌套不超过2-3层
规则21:避免跨编译单元的初始化依赖
- 静态初始化顺序问题是经典陷阱
- 用函数内静态变量替代
规则22:最小化定义依赖,避免循环依赖
- 头文件依赖应形成DAG
- 使用前向声明减少依赖
规则23:让头文件自给自足
- 头文件应能独立编译
- 包含所需的所有依赖
规则24:始终写内部#include guards,从不写外部#include guards
- 使用#if !defined或#pragma once
- 不要依赖外部定义的guard宏
四、函数与运算符
规则25:按值、(智能)指针或引用适当取参
- 小对象按值传递
- 大对象用const引用
- 可空参数用指针
规则26:保持重载运算符的自然语义
- operator==应该是对称的
- operator<<应该返回ostream引用
规则27:优先使用算术和赋值运算符的标准形式
- 实现a += b 比 a + b 更高效
- operator+= 应返回 *this
五、异常处理与资源管理
规则28-30:异常安全级别
- 基本保证:无资源泄漏,状态合法
- 强保证:操作成功或无变化
- 不抛掷保证:永不抛出异常
规则31-35:RAII深化的应用
- 用智能指针管理动态内存
- 用lock_guard/unique_lock管理锁
- 用自定义deleter扩展RAII
关键洞察
- 静态检查优于动态检查:能在编译期发现的问题,绝不让它跑到运行时
- const是朋友:正确使用const可以捕获大量错误
- RAII是C++的灵魂:资源管理必须通过对象生命周期来实现
- 简单优于复杂:大多数情况下,简单的代码比复杂的代码更好
- 测量驱动优化:优化必须有数据支持,否则只是在猜测
与其他知识的关联
- Effective C++ - Scott Meyers的经典著作,与本规范互补
- Effective Modern C++ - C++11/14新特性的规范使用
- Modern C++ Design - Andrei Alexandrescu的另一经典,Policy-Based Design
- Google开源项目风格指南(中文版) - Google团队的C++风格规范
可行动点
- 在项目中启用最高警告级别(-Wall -Wextra -Werror)
- 用static_assert替代运行时类型检查
- 全面使用智能指针,消除裸new/delete
- 为所有公有接口添加const正确性标注
- 建立代码审查清单,重点关注设计而非格式