当前位置:天才代写 > tutorial > C语言/C++ 教程 > Google C++编程气势气魄指南(六):代码注释

Google C++编程气势气魄指南(六):代码注释

2017-11-04 08:00 星期六 所属: C语言/C++ 教程 浏览:572

副标题#e#

注释

注释固然写起来很疾苦,但对担保代码可读性至为重要,下面的法则描写了应该注释什么、注释在哪儿。虽然也要记着,注释简直很重要,但最好的代码自己就是文档(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文件要对所声明的类的成果和用法作简朴说明,.cc文件包括了更多的实现细节或算法接头,假如你感受这些实现细节或算法接头对付阅读有辅佐,可以把.cc中的注释放到.h中,并在.cc中指出文档在.h中。

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

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),文档说明之。假如该类的实例可被多线程会见,利用时务必留意文档说明。


#p#副标题#e#

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 this object”这样的注释是没有意义的。说明结构函数对参数做了什么(譬喻,是否是指针的所有者)以及析构函数清理了什么,假如都是无关紧急的内容,直接省掉注释,析构函数前没有注释是很正常的。

函数界说:

每个函数界说时要以注释说明函数成果和实现要点,如利用的大度代码、实现的扼要步调、如此实现的来由、为什么前半部门要加锁尔后半部门不需要。

不要从.h文件或其他处所的函数声明处直接复制注释,扼要说明函数成果是可以的,但重点要放在如何实现上。

#p#副标题#e#

5.变量注释(Variable Comments)

凡是变量名自己足以很好说明变量用途,特定环境下,需要特别注释说明。

类数据成员:

每个类数据成员(也叫实例变量或成员变量)应注释说明用途,假如变量可以接管NULL或-1等警戒值(sentinel values),须说明之,如:

#p#分页标题#e#

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.实现注释(Implementation 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.

#p#副标题#e#

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

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

注释一般是包括适当大写和句点(.)的完整的句子,短一点的注释(如代码行尾的注释)可以随意点,依然要留意气势气魄的一致性。完整的句子可读性更好,也可以说明该注释是完整的而不是一点不成熟的想法。

固然被别人指出该用分号(semicolon)的时候用了逗号(comma)有点难过。清晰易读的代码照旧很重要的,适当的标点、拼写和语法对此会有所辅佐。

8.TODO注释(TODO Comments)

对那些姑且的、短期的办理方案,或已经够好但并不完美的代码利用TODO注释。

这样的注释要利用全大写的字符串TODO,后头括号(parentheses)里加上你的台甫、邮件地点等,还可以加上冒号(colon):目标是可以按照统一的TODO名目举办查找:

// TODO([email protected]): 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.注释要言简意赅,不要拖沓冗余,巨大的对象简朴化和简朴的对象巨大化都是要被藐视的;

#p#分页标题#e#

4.对付Chinese coders来说,用英文注释照旧用中文注释,it is a problem,但不管奈何,注释是为了让别人看懂,莫非是为了炫耀编程语言之外的你的母语或外语程度吗;

5.注释不要太乱,适当的缩进才会让人乐意看,但也没有须要划定注释从第几列开始(我本身写代码的时候总喜欢这样),UNIX/LINUX下还可以约定是利用tab照旧space,小我私家倾向于space;

6.TODO很不错,有时候,注释确实是为了标志一些未完成的或完成的不尽如人意的处所,这样一搜索,就知道尚有哪些活要干,日志都省了。

 

    关键字:

天才代写-代写联系方式