Google c++编程规范------注释

在我写一起学c++()中说道注释的重要性,特意找了Google c++编程规范给大家参考。希望能对大家有所帮助,并且在以后为大家继续更新相应的规范要求

 

注释虽然写起来很痛苦,但对保证代码可读性至为重要,下面的规则描述了应该注释什么、

注释在哪儿。当然也要记住,注释的确很重要,但最好的代码本身就是文档( self-

documenting ,类型和变量命名意义明确要比通过注释解释模糊的命名好得多。

注释是为别人(下一个需要理解你的代码的人)而写的,认真点吧,那下一个人可能就是

1.注释风格  Comment Style

使用 // /* */ ,统一就好。

// /* */ 都可以, // 只是用的更加广泛,在如何注释和注释风格上确保统一。

2.文件注释  File Comments

在每一个文件开头加入版权公告,然后是文件内容描述。

法律公告和作者信息

每一文件包含以下项,依次是:

1) 版权( copyright statement :如 Copyright 2008 Google Inc.

2) 许可版本( license boilerplate :为项目选择合适的许可证版本,如 Apache 2.0

BSD LGPL GPL

3) 作者( author line :标识文件的原始作者。

如果你对其他人创建的文件做了重大修改,将你的信息添加到作者信息里,这样当其他人

该文件有疑问时可以知道该联系谁。

文件内容

每一个文件版权许可及作者信息后,都要对文件内容进行注释说明。

通常, .h 文件要对所声明的类的功能和用法作简单说明, .cpp 文件包含了更多的实现细节

算法讨论,如果你感觉这些实现细节或算法讨论对于阅读有帮助,可以把 .cpp 中的注释放

.h 中,并在 .cpp 中指出文档在 .h 中。

不要单纯在 .h .cpp 间复制注释,复制的注释偏离了实际意义。

3.类注释Class Comments

每个类的定义要附着描述类的功能和用法的注释。

// 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 {

...

};

如果你觉得已经在文件顶部详细描述了该类,想直接简单的来上一句完整描述见文件顶部

的话,还是多少在类中加点注释吧。

如果类有任何同步前提( synchronization assumptions ,文档说明之。如果该类的实

例可被多线程访问,使用时务必注意文档说明。

4. 函数注释 Function Comments

函数声明处注释描述函数功能,定义处描述函数实现。

函数声明

注释于声明之前,描述函数功能及用法,注释使用描述式( "Opens the file" )而非指令

"Open the file" );注释只是为了描述函数而不是告诉函数做什么。通常,注释不会描

述函数如何实现,那是定义部分的事情。

函数声明处注释的内容:

1) inputs (输入) outputs (输出)

2) 对类成员函数而言:函数调用期间对象是否需要保持引用参数,是否会释放这些参数;

3) 如果函数分配了空间,需要由调用者释放;

4) 参数是否可以为 NULL

5) 是否存在函数使用的性能隐忧( performance implications

6) 如果函数是可重入的( re-entrant ,其同步前提( synchronization assumptions

是什么?

举例如下:

// Returns an iterator for this table. It is the client's

// responsibility to delete the iterator when it is done with it,

// and it must not use the iterator once the GargantuanTable object

// on which the iterator was created has been deleted.

//

// The iterator is initially positioned at the beginning of the table.

//

// This method is equivalent to:

// Iterator* iter = table->NewIterator();

// iter->Seek("");

// return iter;

// If you are going to immediately seek to another place in the

// returned iterator, it will be faster to use NewIterator()

// and avoid the extra seek.

Iterator* GetIterator() const;

但不要有无谓冗余或显而易见的注释,下面的注释就没有必要加上 returns false

otherwise ,因为已经暗含其中了:

// Returns true if the table cannot hold any more entries.

bool IsTableFull();

注释构造 / 析构函数时,记住,读代码的人知道构造 / 析构函数是什么,所以 destroys thi s

object 这样的注释是没有意义的。说明构造函数对参数做了什么(例如,是否是指针的所

有者)以及析构函数清理了什么,如果都是无关紧要的内容,直接省掉注释,析构函数前

有注释是很正常的。

函数定义

每个函数定义时要以注释说明函数功能和实现要点,如使用的漂亮代码、实现的简要步骤、

如此实现的理由、为什么前半部分要加锁而后半部分不需要。

不要从 .h 文件或其他地方的函数声明处直接复制注释,简要说明函数功能是可以的,但重

点要放在如何实现上。

5.变量注释 Variable Comments

通常变量名本身足以很好说明变量用途,特定情况下,需要额外注释说明。

类数据成员

每个类数据成员(也叫实例变量或成员变量)应注释说明用途,如果变量可以接受 NULL -1

警戒值( sentinel values ,须说明之,如:

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;

6. 6. 6. 6. 实现注释 Implementation Implementation Implementation Implementation Comments Comments Comments Comments

对于实现代码中巧妙的、晦涩的、有趣的、重要的地方加以注释。

代码前注释

出彩的或复杂的代码块前要加注释,如:

// 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;

}

行注释

比较隐晦的地方要在行尾加入注释,可以在代码之后空两格加行尾注释,如:

// If we have enough memory, mmap the data portion too.

mmap_budget = max<int64>(0, mmap_budget - index_->length());

if (mmap_budget >= data_size_ && !MmapData(mmap_chunk_bytes, mlock))

return; // Error already logged.

注意,有两块注释描述这段代码,当函数返回时注释提及错误已经被记入日志。

前后相邻几行都有注释,可以适当调整使之可读性更好:

...

DoSomething(); // Comment here so the comments line up.

DoSomethingElseThatIsLonger(); // Comment here so there are two spaces between

// the code and the comment.

...

NULL true/false 1 2 3  …:

向函数传入、布尔值或整数时,要注释说明含义,或使用常量让代码望文知意,比较一下:

bool success = CalculateSomething(interesting_value,

10,

false,

NULL); // What are these arguments??

和:

bool success = CalculateSomething(interesting_value,

10, // Default base value.

false, // Not the first time we're calling

this.

NULL); // No callback.

使用常量或描述性变量:

const int kDefaultBaseValue = 10;

const bool kFirstTimeCalling = false;

Callback *null_callback = NULL;

bool success = CalculateSomething(interesting_value,

kDefaultBaseValue,

kFirstTimeCalling,

null_callback);

 

不要

注意永远不要用自然语言翻译代码作为注释,要假设读你代码的人 C++ 比你强 :D

// Now go through the b array and make sure that if i occurs,

// the next element is i+1.

... // Geez. What a useless comment.

7.标点、拼写和语法 Punctuation, Spelling and Grammar

留意标点、拼写和语法,写的好的注释比差的要易读的多。

注释一般是包含适当大写和句点( . )的完整的句子,短一点的注释(如代码行尾的注释)

可以随意点,依然要注意风格的一致性。完整的句子可读性更好,也可以说明该注释是完

的而不是一点不成熟的想法。

虽然被别人指出该用分号( semicolon 的时候用了逗号( comma 有点尴尬。清晰易

的代码还是很重要的,适当的标点、拼写和语法对此会有所帮助。

8. TODO注释 TODO Comments

对那些临时的、短期的解决方案,或已经够好但并不完美的代码使用 TODO 注释。

这样的注释要使用全大写的字符串 TODO ,后面括号( parentheses 里加上你的大名、邮

件地址等,还可以加上冒号( colon :目的是可以根据统一的 TODO 格式进行查找:

// TODO(kl@gmail.com): Use a "*" here for concatenation operator.

// TODO(Zeke) change this to use relations.

如果加上是为了在将来某一天做某事,可以加上一个特定的时间( "Fix by November

2005" )或事件( "Remove this code when all clients can handle XML

responses." )。

 

 

1. 关于注释风格,很多 C++ coders更喜欢行注释, C coders或许对块注释依然

有独钟,或者在文件头大段大段的注释时使用块注释;

2. 文件注释可以炫耀你的成就,也是为了捅了篓子别人可以找你;

3. 注释要言简意赅,不要拖沓冗余,复杂的东西简单化和简单的东西复杂化都是要被鄙

的;

4.对于 Chinese coders 来说,用英文注释还是用中文注释, it is a problem,但

管怎样,注释是为了让别人看懂,难道是为了炫耀编程语言之外的你的母语或外语水平吗

5. 注释不要太乱,适当的缩进才会让人乐意看,但也没有必要规定注释从第几列开始(

自己写代码的时候总喜欢这样), UNIX/LINUX下还可以约定是使用 tab 还是 space

个人倾向于 space

6. TODO 很不错,有时候,注释确实是为了标记一些未完成的或完成的不尽如人意的地

这样一搜索,就知道还有哪些活要干,日志都省了。

 

 

个人网站http://www.ravedonut.com/

posted @ 2011-07-28 21:03  狂吼的面包圈  阅读(3990)  评论(0编辑  收藏  举报