1. 什么样的注释是不需要的
下面的例子中的全部注释没有提供任何新的信息,所以没有价值。
不要为能从代码中快速推断的事实写注释。
1 // The class definition for Account 2 class Account { 3 public: 4 // Constructor 5 Account(); 6 7 // Set the profit member to a new value 8 void SetProfit(double profit); 9 10 // Return the profit from this Account 11 double GetProfit(); 12 };
2. 不要为了注释而注释
没有价值的注释:
1 // Find the Node in the given subtree, with the given name, using the given depth.
2 Node* FindNodeInSubtree(Node* subtree, string name, int depth);
如果想要在这注释,最好能给出更多重要的细节:
1 // Find a Node with the given 'name' or return NULL.
2 // If depth <= 0, only 'subtree' is inspected.
3 // If depth == N, only 'subtree' and N levels below are inspected.
4 Node* FindNodeInSubtree(Node* subtree, string name, int depth);
3. 应当使用好的变量名,而不是给不好的名字加注释
DeleteRegistry听上去是一个危险的名字,注释是为了澄清困惑
1 // Releases the handle for this key. This doesn't modify the actual registry.
2 void DeleteRegistry(RegistryKey* key);
倒不如直接使用一个能自我说明的名字
1 void ReleaseRegistryHandle(RegistryKey* key);
4. 记录你的思想
(1)加入“导演评论”
// 出乎意料的是,对于这些数据,用二叉树比用哈希表快40%
// 哈希运算比左右比较大得多
上面的注释会说明一条很重要的经验,让读者不要为了无谓的优化浪费时间
1 // 作为整体可能会丢掉几个词,但这不是什么问题。要100%解决太难了
上面的注释说明了一个小问题不是bug,不用过多浪费时间修复。
1 // 这个类正变得越来越乱
2 // 也许我们应该建立一个子类ResourceNode来整理
上面的注释鼓励下一个人改正它,并给出了具体建议。
(2)为代码中的瑕疵写注释
标记 通常的含义 TODO: 有待处理的事情 FIXME: 已知的无法运行的代码 HACK: 对某个问题的粗糙的解决方案 XXX: 危险!这里有问题
具体应遵循团队的规范
(3)给常量加注释
下面的注释告诉读者:常量值设置成1就太低了,50可能就太夸张了
const int NUM_THREADS = 8 // as long as it's >= 2 * num_processors, that's good enough.
可能常量的名字已经够清楚,然而很多常量可以通过加注释进行改进,只需记录下当时的想法而已。
1 image_quality = 0.72; // users thought 0.72 gave the best size/quality tradeoff
5. 站在读者的角度
(1)意料之中的提问
读者可能会问为什么不用data.clear(),可以在注释中回答此问题
struct Recorder { vector<float> data; //... void Clear() {// Force vector to relinquish its memory (look up "STL swap trick") vector<float>().swap(data); } };
(2)公布可能的陷阱
这个函数可能会花一分钟时间。如果没有注释,可能有人在不知情的情况下错误地调用这个函数,导致邮件服务器宕机时,程序被挂起
// 调用外部服务器来发送邮件。(1分钟后超时) void SendEmail(string to, string subject, string body);
(3)“全局观”注释
对于新成员来讲,最难的事情之一就是理解全局观。几句精心选择的话,比什么都没有强多了。
// 这个文件包含一些辅助函数,为我们的文件系统提供了更便利的接口 // 它处理了文件权限及其他基本的细节
(4)总结性注释
下面的注释很好地总结了低层代码
# Find all the items that customers purchased for themselves. for customer_id in all_customers: for sale in all_sales[customer_id].sales: if sale.recipient == customer_id: #...
总结性注释使得读者可以在深入了解细节之前就能得到其主旨
5. 克服“作者心理阻滞”
很多程序员不喜欢写注释,因为要写出好的注释感觉好像要花很多功夫。通过一下方式可以克服这种心理:
(1)最好的办法就是现在就开始写,把心里想的写下来就好了,可能措辞会有些含糊,但是起码比没有强。
(2)读一下这段注释,看看也没有什么可以改进的地方。
(3)不断改进。