精简版GoogleC++规范
头文件
#define保护
所有头文件都应该有#define保护来防止头文件被多重包含,命名格式是:
#ifndef FOO_BAR_BAZ_H_
#define FOO_BAR_BAZ_H_
...
#endif // FOO_BAR_BAZ_H_
前置声明
使用#include包含需要的头文件,避免使用前置声明。
#include路径
项目内头文件应按照项目源代码目录树结构排列,避免使用.(当前目录)和..(上级目录)。
#include顺序
- 源文件相关的头文件,比如:
logging.cc的头文件logging.h - C系统文件
- C++系统文件
- 其他库的头文件
- 本项目内的头文件
作用域
命名空间
鼓励使用命名空间,命名空间的名称可基于项目名或路径。禁止使用using。
匿名命名空间和静态变量
在.cc中定义一个不需要被外部引用的变量时,可以将它们放在匿名命名空间或声明为static。
// 声明为static
static int a = 1;
// 使用匿名命名空间
namespace{int b = 1;
} // namespace
非成员函数、静态成员函数和全局函数
使用静态成员函数或命名空间内的非成员函数,尽量不要用裸的全局函数。
局部变量
将函数变量尽可能置于最小作用域内,并在变量声明时进行初始化。
静态和全局变量
禁止定义全局和静态的对象,原生数据类型是可以的。
类
构造函数的职责
构造函数不允许调用虚函数。不要再无法报出错误时,进行可能失败的初始化。可以考虑添加一个Init()方法。
构造函数隐式类型转换
在类型定义中,类型转换运算符和单参数构造函数都应当用explicit进行标记,抑制隐式类型转换。
可拷贝类型和可移动类型
如果你的类型需要,就让他们支持拷贝/移动,否则,就把隐式产生的拷贝和移动函数禁用。
结构体和类
仅当只有数据成员时使用struct,其他一概使用class。
继承
尽量使用组合。如果使用继承的话,定义为public继承。
声明顺序
将相似的声明放在一起,将public部分放在最前,后跟protected,最后是private。
顺序如下:
- 类型定义
- 常量
- 工厂函数
- 构造函数
- 赋值运算符
- 析构函数
- 其他函数
- 数据成员
函数
输入和输出
函数输出倾向于使用返回值,而不是输出参数。返回值使用按值返回,否则按引用返回。避免返回指针,除非它可以为空。
输入参数是值参或const引用(所有引用传递的参数必须加上const),输出参数为指针。
排序函数参数时,将所有输入参数放在所有输出参数之前。
编写简短函数
尽量编写简短,凝练的函数。如果函数超过40行,可以思索一下能不能在不影响程序结构的前提下对其进行分割。
函数重载
若要使用函数重载,则必须能让读者一看调用点就胸有成竹,而不用花心思猜测调用的重载函数到底是哪一个。这一规则也适用于构造函数。
缺省参数
尽量不使用缺省参数语法,可以修改成函数重载。
其他
类型转换
使用C++的类型转换,比如:static_cast<>()。不要使用int y = (int)x或int 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 | 缺陷,链接到所有缺陷汇总的缺陷列表 |
| @todo | TODO,链接到所有TODO汇总的TODO列表 |
| @example | 使用例子说明 |
| @remarks | 备注说明 |
| @pre | 函数前置条件 |
| @deprecated | 函数过时说明 |
格式
行长度
每一行代码字符数不超过80个,不强制。
空格还是制表位
只使用空格,缩进采用2个空格。
函数声明和定义
- 返回类型和函数名在同一行。
- 参数也尽量和函数名放在同一行,如果放不下就对形参分行。
- 如果返回类型与函数声明或定义分行了, 不要缩进。
- 左圆括号总是和函数名在同一行。
- 函数名和左圆括号间永远没有空格。
- 圆括号与参数间没有空格。
- 左大括号总在最后一个参数同一行的末尾处, 不另起新行。
- 右大括号总是单独位于函数最后一行, 或者与左大括号同一行。
- 右圆括号和左大括号间总是有一个空格。
- 换行后的参数保持 4 个空格的缩进。
预处理指令
预处理指令不要缩进,从行首开始。
命名空间格式化
命名空间内容不缩进。
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
