本笔记基于 Google C++ Style Guide 整理,聚焦核心规则与常见场景,便于快速查阅。

Google C++ Style Guide

0. 核心理念

Google 规范的终极宗旨是:可读性 > 一切,一致性 > 个人偏好。代码被阅读的次数远多于被编写的次数——清晰胜于巧妙。

原则说明
可读性优先代码是写给人看的,只是顺便给机器执行
一致性至上同一项目风格统一比“理论上最优”更重要
安全与健壮避免隐式类型转换、未定义行为、资源泄漏

根据谷歌工程团队统计,遵循统一风格的代码库:新成员上手速度提升65%,代码审查时间减少30%,生产环境 bug 率降低22%。


1. 头文件

1.1 自给自足

——Self-contained

所有头文件必须能够独立编译。用户和重构工具不应为特别场合而包含额外头文件。

// my_class.h
#ifndef MY_PROJECT_MY_CLASS_H_   // ← 必须有头文件保护
#define MY_PROJECT_MY_CLASS_H_
 
#include <string>   // ← 显式包含所有依赖,不依赖间接包含
 
class MyClass {
 public:
  explicit MyClass(const std::string& name);
  void DoSomething();
 private:
  std::string name_;
};
 
#endif

1.2 头文件保护

——Include Guard

强制使用 #ifndef 格式,禁止 #pragma once

#ifndef PROJECT_DIR_FILE_H_   // 路径相对项目根目录,全大写
#define PROJECT_DIR_FILE_H_
 
// ...
 
#endif

1.3 前置声明

——Forward Declaration

能前向声明就不 #include,减少编译依赖。

// foo.h
class Bar;  // 前置声明,不包含 Bar.h
 
class Foo {
  Bar* bar_;  // 仅需指针,不需完整定义
};

但不要过度前置声明——头文件仍必须自给自足。

1.4 内联函数

——Inline Functions

仅当函数体极短小(通常 ≤10 行)时使用 inline。内联函数定义必须放在 .h 文件中。

1.5 #include 顺序

按以下顺序分组,每组之间空一行:

  1. 本文件对应的头文件(.cc 文件优先包含自己的 .h
  2. C 系统头文件
  3. C++ 标准库头文件
  4. 其他库头文件
  5. 项目内头文件

2. 作用域

2.1 命名空间

必须将代码置于命名空间中(禁用全局命名空间),但禁止 using namespace std; 防止污染。

// .h 文件
namespace my_project {
class MyClass { ... };
}  // namespace my_project

.cc 文件中可使用匿名命名空间封装局部辅助函数,使其仅在本编译单元可见。

2.2 局部变量

尽可能在首次使用时声明并初始化,缩小作用域。

2.3 静态和全局变量

禁止使用非 constexpr 的全局变量和静态变量(有静态初始化顺序问题)。


3. 类

3.1 构造函数

避免在构造函数中执行复杂或可能失败的操作。

  • 若初始化可能失败,改用工厂函数
  • 单参数构造函数必须使用 explicit 防止意外隐式转换
class MyClass {
 public:
  explicit MyClass(int value);  // ✅ 防止隐式转换
  // MyClass obj = 42;  // 编译错误
};

3.2 组合 vs 继承

优先选择组合(Composition)。若必须继承,仅使用 public 继承。

3.3 结构体 vs 类

struct 仅用于纯数据聚合(只有 public 成员,无方法);只要包含方法,必须使用 class

struct Point {
  int x;
  int y;
};  // ✅ 纯数据,用 struct
 
class DataProcessor {
 public:
  void Process();
 private:
  int data_;
};  // ✅ 有方法,用 class

3.4 声明顺序

类内严格按 public:protected:private: 顺序声明。


4. 现代 C++ 特性

Google 规范在 2025 年版中明确要求使用 C++20 标准,禁止非标准扩展。

特性规则说明
智能指针优先 std::unique_ptr,确需共享时用 std::shared_ptr严禁 auto_ptr(已弃用)
空指针永远使用 nullptr禁止 NULL0
auto 关键字仅限类型冗长或显著提升可读性的场景避免滥用隐藏类型信息
范围 for 循环优先使用 for (const auto& elem : container)减少迭代器错误
右值引用仅用于移动语义和完美转发不滥用
异常Google 禁用 C++ 异常这是其最显著特色之一,源于性能与控制流可预测性考量
RTTI禁用 dynamic_casttypeinfo
类型转换使用 static_cast / const_cast / reinterpret_cast禁止 C 风格 (int)x
Lambda允许但谨慎使用避免复杂捕获
title:Important
Google 已于 2023 年 12 月正式宣布停止维护该规范,并推荐团队根据自身需求采用更现代的实践(如 C++17/20 特性、Clang-Tidy、静态分析等)。但规范的核心思想仍深刻影响着业界。

5. 命名约定

Google 规范的最高宗旨之一就是通过命名快速获知名字代表的类型,无需查找声明。

元素命名格式示例
文件名全小写 + 下划线my_class.cc, http_server.h
类/结构体/枚举帕斯卡拼法(大驼峰)MyExcitingClass, UrlTable
函数/方法帕斯卡拼法(大驼峰)DoSomething(), GetValue()
局部变量全小写 + 下划线local_variable, index
类成员变量全小写 + 结尾下划线health_points_, name_
常量(const/constexpr)k + 大驼峰kDaysInAWeek, kMaxBuffer
宏定义全大写 + 下划线MY_MACRO, LOG_ERROR
命名空间全小写 + 下划线my_namespace

通用命名规则

函数命名、变量命名、文件命名要有描述性,少用缩写。别心疼空间,让代码易于新读者理解更重要。

int price_count_reader;   // ✅ 清晰
int num_errors;           // ✅ "num" 常见
int n;                    // ❌ 莫名其妙
int nerr;                 // ❌ 奇怪缩写
int pc_reader;            // ❌ "pc" 含义太多
int cstmr_id;             // ❌ 随意删减字母

关于私有成员变量以 _ 结尾而非开头(避免与系统保留标识符冲突),以及全局变量使用 g_ 前缀(极少使用),这些细节应在实际编码中遵循。


6. 格式

规则说明
行长度≤ 80 字符(实际项目可放宽至 100 或 120)
缩进4 空格,禁止使用 Tab
大括号Attach 风格:左大括号与语句同一行
指针/引用星号/& 符号与类型绑定(int* ptr 而非 int *ptr

函数声明与定义

void MyFunction(int param1,         // 参数过长时换行对齐
                const string& param2) {
  // ...
}

条件与循环

if (condition) {      // 左大括号与条件同行
  DoSomething();
} else {
  DoOtherthing();
}
 
for (int i = 0; i < 10; ++i) {
  Process(i);
}

7. 注释

使用 // 风格,函数需用 Doxygen 风格注释,说明功能、参数、返回值。

// MyClass.h
class MyClass {
 public:
  // Computes the average of the given numbers.
  // Returns 0 if the list is empty.
  double ComputeAverage(const std::vector<double>& numbers);
};

TODO 注释

// TODO(username): Fix this edge case when input is empty.

8. 争议条款

争议项内容
输出参数:指针 vs 引用早期强制用指针表示输出参数。最新规范已更新,推荐使用引用作为输出参数的首选方式,因为引用天然排除了空指针风险,类型安全更强。当需要可选输出时,考虑 std::optional<T&>
禁止异常这是 Google 规范最具争议的条款,与 C++ Core Guidelines 等现代实践相悖

9. 自动化工具

工具用途
cpplintGoogle 官方提供的代码风格检查工具,可集成到 CI 流程中自动检查是否符合规范
clang-format配合 Google 风格配置(BasedOnStyle: Google),自动格式化代码

10. 与其他规范的对比

Google 规范与 LLVM 规范是业界两大主流标准,核心差异如下:

差异维度GoogleLLVM
缩进4 空格2 空格
大括号Attach(同行)Allman(独占一行)
using namespace禁止允许在模块作用域谨慎使用
命名禁止下划线前缀允许下划线突出作用域
异常严格限制更灵活