Google C++编程风格指南阅读笔记之命名、注释和格式
文章目录
- 前言
- 命名约定
- 类型命名
- 变量命名
- 枚举命名
- 宏的命名
- 注释
- 注释风格
- 文件注释
- 类注释
- 函数注释
- 变量注释
- 类的数据成员
- 全局变量
- 实现注释
- TODO注释
- 格式
- 行长度
- 空格还是制表符
- 函数声明和定义
- lambda表达式
- 条件语句
- 指针和引用
- 变量及数组初始化
- 预处理指令
- 构造函数初始化列表
- 名字空间格式化
前言
本文源自Google C++编程风格指南,砍掉了其中比较common的部分,保留了个人认为最有价值的部分,并合入了自己的理解。原文下载连接:Google C++编程风格指南
命名约定
类型命名
类型名称的每个单词首字母均大写,不包含下划线如:MyExecitingClass
,IOService
变量命名
变量名一律小写,单词之间使用下划线连接。类和结构体的成员变量以m_
开头(原文是类的成员变量以_
结尾,结构体不用)
枚举命名
枚举的命名应当和宏一致
宏的命名
宏的命名使用全大写字母加下划线,如MY_MACRO
注释
注释风格
使用/*… */风格,每行注释前加*
,这样更为美观,阅读起来赏心悦目
文件注释
在每一个文件开头加入版权公告(简单项目可省略),然后是文件内容描述
文件内容:
通常.h文件要对所声明的类的功能和用法做简单说明,.cc文件通常包含了更多的实现细节或算法技巧讨论。不要简单的在.h和.cc文件之间复制注释,这偏离了注释的实际意义
类注释
每个类的定义都需要附带一份注释,描述类的功能和用法。
/* Iterates over the contents of a GargantuanTable. Sample usage:* GargantuanTable_Iterator* iter = table->NewIterator();* for (iter->Seek("foo"); !iter->done(); iter->Next()) {* process(iter->key(), iter->value());* }* delete iter;*/
class GargantuanTable_Iterator {...
};
如果类有任何同步的前提,需要在文档说明。如果该类的实例可被多线程访问,要特别注意文档说明多线程环境下相关的规则和使用。
函数注释
函数声明处注释描述函数的功能;定义处描述函数的实现
函数声明处注释的内容:
- 函数的参数,参数的意义,以及是输入参数还是输出参数
- 函数功能
- 函数的返回值
- 函数的注意事项
如(摘自workflow)
/*** @brief register default port for one scheme string* @param[in] scheme scheme string* @param[in] port default port value* @note ...* @warning No effect when scheme is "http"/"https"/"redis"/"rediss"/"mysql"/"kafka"*/static void register_scheme_port(const std::string& scheme, unsigned short port);
这样的代码既美观又清晰
但不要过度注释,那些显而易见用途的函数就不用过多的注释了
函数定义:
重要的函数定义时要说明函数功能和实现要点,比如说说你的编程技巧,实现的大致步骤,或解释为何如何实现
变量注释
类的数据成员
每个类数据成员都应该用注释说明其用途。如:
private:
/* Keeps track of the total number of entries in the table.
* Used to ensure we do not go over the limit. -1 means
* that we don't yet know how many entries the table has.*/
int num_total_entries_;
全局变量
和数据成员一样,所有全局变量也要注释说明含义及用途。如:
/* The total number of tests cases that we run through in this regression test.*/
const int kNumTestCases = 6;
实现注释
对于代码中巧妙的,晦涩的,有趣的,重要的地方加以注释
/* Divide result by two, taking into account that x* contains the carry from the add.*/
for (int i = 0; i < result->size(); i++) {x = (x << 8) + (*result)[i];
(*result)[i] = x >> 1;
x &= 1;
}
TODO注释
对那些临时的、短期的解决方案,或仍有改进空间的代码使用TODO注释
TODO 注释要使用全大写的字符串 TODO, 在随后的圆括号里写上你的大名, 邮件地址, 或其它身份标识. 冒号是可选的. 主要目的是让添加注释的人 (也是可以请求提供更多细节的人) 可根据规范的 TODO 格式进行查找. 添加 TODO注释并不意味着你要自己来修正.
/* TODO(kl@gmail.com): Use a "*" here for concatenation operator. */
/* TODO(Zeke) change this to use relations. */
格式
行长度
每行代码不要过长,影响阅读,如果实在过长,可以用\
符号隔断成两行较短的代码行,参考长度为80个字符
空格还是制表符
统一使用4个空格作为缩进,调整你的编辑器来将制表符转为空格
函数声明和定义
返回类型和函数名在同一行, 参数也尽量放在同一行,如果放不下就对形参分行。
过长时可以这样:
ReturnType LongClassName::ReallyReallyReallyLongFunctionName(Type par_name1, // 4 空格缩进Type par_name2,Type par_name3) {DoSomething(); // 2 空格缩进
...
}
注意以下几点:
• 如果返回类型和函数名在一行放不下,分行。
• 如果返回类型那个与函数声明或定义分行了,不要缩进。
• 左圆括号总是和函数名在同一行;
• 函数名和左圆括号间没有空格;
• 圆括号与参数间没有空格;
• 左大括号总在最后一个参数同一行的末尾处;
• 如果其它风格规则允许的话,右大括号总是单独位于函数最后一行,或者与左大括号同一行。
• 右大括号和左大括号间总是有一个空格;
• 函数声明和定义中的所有形参必须有命名且一致;
• 所有形参应尽可能对齐;
• 换行后的参数保持 4 个空格的缩进;
如果有些参数没有用到, 在函数定义处将参数名注释起来:
/* 接口中形参恒有命名。*/
class Shape {public:
virtual void Rotate(double radians) = 0;
}
/* 声明中形参恒有命名。*/
class Circle : public Shape {public:
virtual void Rotate(double radians);
}
/* 定义中注释掉无用变量。 */
void Circle::Rotate(double /*radians*/) {}
/* 差 - 如果将来有人要实现,很难猜出变量是干什么用的。 */
void Circle::Rotate(double) {}
lambda表达式
不要使用默认捕获!! 且使用lamdba表达式时要注意空悬指针等问题
条件语句
所有情况下 if 和左圆括号间都有个空格. 右圆括号和左大括号之间也要有个空格:
if(condition) /* 差 - IF 后面没空格。*/
if (condition){ /* 差 - { 前面没空格。 */
if(condition){ /* 变本加厉地差。 */
if (condition) { /* 可 - IF 和 { 都与空格紧邻。*/
如果能增强可读性, 简短的条件语句允许写在同一行. 只有当语句简单并且没有使用 else 子句时使用:
if (x == kFoo) return new Foo();
if (x == kBar) return new Bar();
如果有else子语句则不行
/* 不可以这样子 - 当有 ELSE 分支时 IF 块却只有一行*/
if (x) DoThis();
else DoThat();
单行语句也一定要加大括号,这是为了后续如果有改动的话,防止出问题
if (condition) {foo;
}
指针和引用
在声明指针变量或参数时, 星号与变量名紧挨:
/* good */
char *ptr = NULL;
/* bad */
char* ptr = NULL;
这样做是为了防止出现歧义,如
char* ptr1 = NULL, ptr2 = NULL;
这里的ptr2实际是一个char
类型,但很容易让人误以为是一个char *
类型。
变量及数组初始化
尽量使用{ }
形式的初始化,但要小心列表初始化 {…} 用 std::initializer_list 构造函数初始化出的类型。非空列表初始化就会优先调用 std::initializer_list, 不过空列表初始化除外,后者原则上会调用默认构造函数。为了强制禁用std::initializer_list 构造函数,请改用括号。
vector<int> v1(100, 1); /* vector中含有100个元素,每个元素都是个1 */
vector<int> v2{100, 1}; /* vector 中含有2个元素,分别是100和1 */
预处理指令
预处理指令不要缩进, 从行首开始。即使预处理指令位于缩进代码块中, 指令也应从行首开始。
/* 可 - directives at beginning of line */
if (lopsided_score) {#if DISASTER_PENDING /* 正确 -- 行开头起。 */DropEverything();
#endifBackToNormal();
}
/* 差 - indented directives */
if (lopsided_score) {#if DISASTER_PENDING /* 错了! "#if" 应该放在行开头 */DropEverything();#endif /* 错了! "#endif" 不要缩进 */BackToNormal();
}
构造函数初始化列表
构造函数初始值列表放在同一行或按四格缩进并排几行
下面两种初始值列表方式都可以接受
/* 当全放在一行合适时: */
MyClass::MyClass(int var) : some_var_(var), some_other_var_(var + 1) {
或者
/* 如果要断成多行,缩进四格,冒号放在第一行初始化句: */
MyClass::MyClass(int var): some_var_(var), /* 4 空格缩进 */some_other_var_(var + 1) { /* 对准 */...DoSomething();...
}
名字空间格式化
名字空间 不要增加额外的缩进层次, 名字空间末尾要加注释说明。例如:
namespace wd{void foo() { /* 正确。命名空间内没有额外的缩进。 */
...
}
} /* namespace */
Google C++编程风格指南阅读笔记之命名、注释和格式相关推荐
- Google C++编程风格指南
[译]Google C++编程风格指南(八)[完] 2008年09月03日 星期三 17:06 原文地址:Google C++ Style Guide 规则之例外 前面说明的编码习惯基本是强制性的,但 ...
- Google Java编程风格指南(献给那些没有良好编码习惯的程序员们)
作者:Hawstein 出处:http://hawstein.com/posts/google-java-style.html 声明:本文采用以下协议进行授权: 自由转载-非商用-非衍生-保持署名|C ...
- Google C++ 编程风格指南:注释
Google C++ 编程风格指南:注释 注释虽然写起来很痛苦, 但对保证代码可读性至关重要. 下面的规则描述了如何注释以及在哪儿注释. 当然也要记住: 注释固然很重要, 但最好的代码本身应该是自文档 ...
- Google Java编程风格指南中文版
作者:Hawstein 出处:http://hawstein.com/posts/google-java-style.html 声明:本文采用以下协议进行授权: 自由转载-非商用-非衍生-保持署名|C ...
- Google Java编程风格指南中文版(转)
作者:Hawstein 出处:http://hawstein.com/posts/google-java-style.html 声明:本文采用以下协议进行授权: 自由转载-非商用-非衍生-保持署名|C ...
- Google Java编程风格指南
Hawstein's Blog Home Archive Categories Sitemap About Su 前言 源文件基础 源文件结构 格式 命名约定 编程实践 Javadoc 后记 前言 这 ...
- 深度解析Google Java 编程风格指南
这份文档是Google Java编程风格规范的完整定义.当且仅当一个Java源文件符合此文档中的规则, 我们才认为它符合Google的Java编程风格. 与其它的编程风格指南一样,这里所讨论的不仅仅是 ...
- Google C++编程风格指南(一):背景
Google 的项目大多使用 C++开发.每一个 C++程序员也都知道,C++具有很多强大的语言特性,但这种强大不可避免的导致它的复杂,而复杂性会使得代码更容易出现 bug.难于阅读和维护. 本指 ...
- Qt——自定义编程风格指南(未完成)
文章目录 前言 一.头文件模板规则 1. 尽量所有"#include"放在.h文件头部 2. "#include"包含的类顺序 3. 头文件中 变量.函数 属性 ...
最新文章
- CSS 圣杯布局升级版---多个固定宽度一个自适应宽度
- AMD芯片支持oracle数据库,oracle 11gR2 amdu 工具可以直接使用
- asp.net中@page指令的属性Inherits、Src、CodeBehind区别
- 年轻人应该谨记的十点
- 将json字符串转换成html,将JSON HTML字符串转换为HTML
- UIScollView Touch事件
- 增城seo搜索引擎优化_搜索引擎seo优化主要从哪里入手?
- PphpStorm常用操作整理
- 炫龙dd2——黑苹果10.14 Clover EFI文件共享
- android调起浏览器设置头部,Android开发:调起手机浏览器
- 室内外地图切换(室内基于ibeacons三点定位)
- 使用阿里的easyexcel 导入xls类型Excel文件报错问题深挖
- IAR中使用IELFTOOL进行软件代码checksum的生成和添加
- DLL的创建和使用(含代码)
- 数据库实验4---数据完整性
- Trinity使用流程
- TIME_WAIT状态和FIN_WAIT_2状态
- 灰色关联分析(系统分析+综合评价)
- Windbg在软件调试中的应用
- coreldraw的线条怎么变成圆头_智能设计 | 建模仿真(3):力学仿真