精简版GoogleC++规范

头文件

#define保护

所有头文件都应该有#define保护来防止头文件被多重包含,命名格式是:<PROJECT>_<PATH>_<FILE>_H_。

#ifndef FOO_BAR_BAZ_H_
#define FOO_BAR_BAZ_H_
...
#endif // FOO_BAR_BAZ_H_

前置声明

使用#include包含需要的头文件,避免使用前置声明。

#include路径

项目内头文件应按照项目源代码目录树结构排列,避免使用.(当前目录)和..(上级目录)。

#include顺序

  1. 源文件相关的头文件,比如:logging.cc的头文件logging.h
  2. C系统文件
  3. C++系统文件
  4. 其他库的头文件
  5. 本项目内的头文件

作用域

命名空间

鼓励使用命名空间,命名空间的名称可基于项目名或路径。禁止使用using

匿名命名空间和静态变量

.cc中定义一个不需要被外部引用的变量时,可以将它们放在匿名命名空间或声明为static

// 声明为static
static int a = 1;
// 使用匿名命名空间
namespace{
	int b = 1;
}	// namespace

非成员函数、静态成员函数和全局函数

使用静态成员函数或命名空间内的非成员函数,尽量不要用裸的全局函数。

局部变量

将函数变量尽可能置于最小作用域内,并在变量声明时进行初始化。

静态和全局变量

禁止定义全局和静态的对象,原生数据类型是可以的。

构造函数的职责

构造函数不允许调用虚函数。不要再无法报出错误时,进行可能失败的初始化。可以考虑添加一个Init()方法。

构造函数隐式类型转换

在类型定义中,类型转换运算符和单参数构造函数都应当用explicit进行标记,抑制隐式类型转换。

可拷贝类型和可移动类型

如果你的类型需要,就让他们支持拷贝/移动,否则,就把隐式产生的拷贝和移动函数禁用。

结构体和类

仅当只有数据成员时使用struct,其他一概使用class

继承

尽量使用组合。如果使用继承的话,定义为public继承。

声明顺序

将相似的声明放在一起,将public部分放在最前,后跟protected,最后是private
顺序如下:

  1. 类型定义
  2. 常量
  3. 工厂函数
  4. 构造函数
  5. 赋值运算符
  6. 析构函数
  7. 其他函数
  8. 数据成员

函数

输入和输出

函数输出倾向于使用返回值,而不是输出参数。返回值使用按值返回,否则按引用返回。避免返回指针,除非它可以为空。
输入参数是值参或const引用(所有引用传递的参数必须加上const),输出参数为指针。
排序函数参数时,将所有输入参数放在所有输出参数之前。

编写简短函数

尽量编写简短,凝练的函数。如果函数超过40行,可以思索一下能不能在不影响程序结构的前提下对其进行分割。

函数重载

若要使用函数重载,则必须能让读者一看调用点就胸有成竹,而不用花心思猜测调用的重载函数到底是哪一个。这一规则也适用于构造函数。

缺省参数

尽量不使用缺省参数语法,可以修改成函数重载。

其他

类型转换

使用C++的类型转换,比如:static_cast<>()。不要使用int y = (int)xint y = int(x)等C风格类型转换方式。

  • static_cast 替代C风格的类型转换,或某个类指针需要明确的向上转换为父类指针。
  • const_cast 去掉const限定符。
  • reinterpret_cast 指针类型和整型或其他指针之间进行不安全的相互转换。仅在你对所做的一切了然于心时使用。
  • dynamic_cast 确认给定的基类指针指向某个派生类的实例,那么就可以使用dynamic_cast将基类指针转换成派生类指针。

const

尽可能的情况下使用const限定符。

宏定义

使用宏时要非常谨慎,尽量使用内联函数、枚举、常量代替。

命名约定

通用命名规则

函数命名,变量命名,文件命名要有描述性,少用缩写。一些广为人知的缩写是允许的。

文件命名

文件名要全部小写,各个单词之间用_连接。eg:my_useful_class.cc

类型命名

类型名称的每个单词首字母均大写,不包含下划线。eg:MyExcitingClass。类型包括:类,结构体,类型定义(typedef),枚举,类型模板参数。

变量命名

  • 普通变量,一律小写,单词之间用下划线连接。eg:table_name
  • 类成员变量,一律小写,单词之间用下划线连接,末尾要接下划线。eg:table_name_
  • 结构体变量,和普通变量一样。

常量命名

以”k“开头,后续所有的单词首字母大写。eg:const int kDaysInAWeek = 7;

函数命名

函数名的所有单词首字母大写(驼峰变量名),没有下划线。对于缩写单词,也要首字母大写。eg:int DrawRgb();

命名空间命名

全部小写,多个单词用下划线连接。

枚举命名

以”k“开头,后续的所有单词首字母大写。eg:

enum UrlTableErrors{
	kOk = 0,
  kErrorOutOfMemory,
  kErrorMalformedInput
};

宏命名

全部大写,单词之间用下划线连接。eg:MY_MACRO_THAT_SCARES_SMALL_CHILDREN

注释

采用Doxygen注释语法。

  • 单行注释 ///
  • 行尾注释 ///<
  • 多行注释:
/**
 *
 */

文件注释

在文件开头加入文件注释。

/**
 * @file 文件名
 * @brief 简介
 * @details 细节
 * @mainpage 工程概览
 * @author 作者
 * @email 邮箱
 * @version 版本号
 * @date 年-月-日
 * @license 版权
 */

类注释

类的注释方式非常简单,使用@brief,后面填写类的概述,换行填写类的详细描述信息。

 /**
 * @brief 类的简单概述
 * 类的详细概述
 */

命名空间、结构体、联合体、枚举定义与类注释方式一致。

函数注释

简约注释

函数注释主要包含函数简介@brief、参数说明@param、返回说明@return、返回值说明@retval

/**
 * @brief 函数简介
 *
 * @param 形参 参数说明
 * @param 形参 参数说明
 * @return 返回说明
 *   @retval value1 返回值说明
 *   @retval value2 返回值说明
 */
详细注释

可以根据需要添加详细说明@detail、注解@note、注意@attention、警告@warning、异常@exception等。

/**
 * @brief 函数简介
 * @detail 详细说明
 * 
 * @param 形参 参数说明
 * @param 形参 参数说明
 * @return 返回说明
 *   @retval value1 返回值说明
 *   @retval value2 返回值说明
 * @note 注解
 * @attention 注意
 * @warning 警告
 * @exception 异常
 */

变量注释

代码前注释
/// 缓存大小
int buf_size = 1024;
代码后注释
int buf_size = 1024;	///< 缓存大小

其它

下面一些标注可以根据需要选择使用

标注说明
@see参考
@class引用类,用于文档生成链接
@var引用该变量,用于文档生成链接
@enum引用枚举,用于文档生成链接
@code代码块开始,与@endcode成对使用
@endcode代码块结束,与@code成对使用
@bug缺陷,链接到所有缺陷汇总的缺陷列表
@todoTODO,链接到所有TODO汇总的TODO列表
@example使用例子说明
@remarks备注说明
@pre函数前置条件
@deprecated函数过时说明

格式

行长度

每一行代码字符数不超过80个,不强制。

空格还是制表位

只使用空格,缩进采用2个空格。

函数声明和定义

  • 返回类型和函数名在同一行。
  • 参数也尽量和函数名放在同一行,如果放不下就对形参分行。
  • 如果返回类型与函数声明或定义分行了, 不要缩进。
  • 左圆括号总是和函数名在同一行。
  • 函数名和左圆括号间永远没有空格。
  • 圆括号与参数间没有空格。
  • 左大括号总在最后一个参数同一行的末尾处, 不另起新行。
  • 右大括号总是单独位于函数最后一行, 或者与左大括号同一行。
  • 右圆括号和左大括号间总是有一个空格。
  • 换行后的参数保持 4 个空格的缩进。

预处理指令

预处理指令不要缩进,从行首开始。

命名空间格式化

命名空间内容不缩进。

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值