7. 命名約定
最重要的一致性規(guī)則是命名管理. 命名的風(fēng)格能讓我們?cè)诓恍枰ゲ檎翌愋吐暶鞯臈l件下快速地了解某個(gè)名字代表的含義: 類型, 變量, 函數(shù), 常量, 宏, 等等, 甚至. 我們大腦中的模式匹配引擎非常依賴這些命名規(guī)則.
命名規(guī)則具有一定隨意性, 但相比按個(gè)人喜好命名, 一致性更重要, 所以無(wú)論你認(rèn)為它們是否重要, 規(guī)則總歸是規(guī)則.
7.1. 通用命名規(guī)則
總述
函數(shù)命名, 變量命名, 文件命名要有描述性; 少用縮寫.
說(shuō)明
盡可能使用描述性的命名, 別心疼空間, 畢竟相比之下讓代碼易于新讀者理解更重要. 不要用只有項(xiàng)目開(kāi)發(fā)者能理解的縮寫, 也不要通過(guò)砍掉幾個(gè)字母來(lái)縮寫單詞.
int price_count_reader; // 無(wú)縮寫int num_errors; // "num" 是一個(gè)常見(jiàn)的寫法int num_dns_connections; // 人人都知道 "DNS" 是什么int n; // 毫無(wú)意義.int nerr; // 含糊不清的縮寫.int n_comp_conns; // 含糊不清的縮寫.int wgc_connections; // 只有貴團(tuán)隊(duì)知道是什么意思.int pc_reader; // "pc" 有太多可能的解釋了.int cstmr_id; // 刪減了若干字母.
注意, 一些特定的廣為人知的縮寫是允許的, 例如用i表示迭代變量和用T表示模板參數(shù).
模板參數(shù)的命名應(yīng)當(dāng)遵循對(duì)應(yīng)的分類: 類型模板參數(shù)應(yīng)當(dāng)遵循類型命名的規(guī)則, 而非類型模板應(yīng)當(dāng)遵循變量命名的規(guī)則.
7.2. 文件命名
總述
文件名要全部小寫, 可以包含下劃線 (_) 或連字符 (-), 依照項(xiàng)目的約定. 如果沒(méi)有約定, 那么 “_” 更好.
說(shuō)明
可接受的文件命名示例:
my_useful_class.cc
my-useful-class.cc
myusefulclass.cc
myusefulclass_test.cc//_unittest和_regtest已棄用.
C++ 文件要以.cc結(jié)尾, 頭文件以.h結(jié)尾. 專門插入文本的文件則以.inc結(jié)尾, 參見(jiàn)頭文件自足.
不要使用已經(jīng)存在于/usr/include下的文件名 (Yang.Y 注: 即編譯器搜索系統(tǒng)頭文件的路徑), 如db.h.
通常應(yīng)盡量讓文件名更加明確.http_server_logs.h就比logs.h要好. 定義類時(shí)文件名一般成對(duì)出現(xiàn), 如foo_bar.h和foo_bar.cc, 對(duì)應(yīng)于類FooBar.
內(nèi)聯(lián)函數(shù)必須放在.h文件中. 如果內(nèi)聯(lián)函數(shù)比較短, 就直接放在.h中.
7.3. 類型命名
總述
類型名稱的每個(gè)單詞首字母均大寫, 不包含下劃線:MyExcitingClass,MyExcitingEnum.
說(shuō)明
所有類型命名 —— 類, 結(jié)構(gòu)體, 類型定義 (typedef), 枚舉, 類型模板參數(shù) —— 均使用相同約定, 即以大寫字母開(kāi)始, 每個(gè)單詞首字母均大寫, 不包含下劃線. 例如:
// 類和結(jié)構(gòu)體class UrlTable { ...class UrlTableTester { ...struct UrlTableProperties { ...// 類型定義typedef hash_map
7.4. 變量命名
總述
變量 (包括函數(shù)參數(shù)) 和數(shù)據(jù)成員名一律小寫, 單詞之間用下劃線連接. 類的成員變量以下劃線結(jié)尾, 但結(jié)構(gòu)體的就不用, 如:a_local_variable,a_struct_data_member,a_class_data_member_.
說(shuō)明
普通變量命名
舉例:
string table_name; // 好 - 用下劃線.string tablename; // 好 - 全小寫.string tableName; // 差 - 混合大小寫
類數(shù)據(jù)成員
不管是靜態(tài)的還是非靜態(tài)的, 類數(shù)據(jù)成員都可以和普通變量一樣, 但要接下劃線.
class TableInfo { ... private: string table_name_; // 好 - 后加下劃線. string tablename_; // 好. static Pool
結(jié)構(gòu)體變量
不管是靜態(tài)的還是非靜態(tài)的, 結(jié)構(gòu)體數(shù)據(jù)成員都可以和普通變量一樣, 不用像類那樣接下劃線:
struct UrlTableProperties { string name; int num_entries; static Pool
結(jié)構(gòu)體與類的使用討論, 參考結(jié)構(gòu)體 vs. 類.
7.5. 常量命名
總述
聲明為constexpr或const的變量, 或在程序運(yùn)行期間其值始終保持不變的, 命名時(shí)以 “k” 開(kāi)頭, 大小寫混合. 例如:
const int kDaysInAWeek = 7;
說(shuō)明
所有具有靜態(tài)存儲(chǔ)類型的變量 (例如靜態(tài)變量或全局變量, 參見(jiàn)存儲(chǔ)類型) 都應(yīng)當(dāng)以此方式命名. 對(duì)于其他存儲(chǔ)類型的變量, 如自動(dòng)變量等, 這條規(guī)則是可選的. 如果不采用這條規(guī)則, 就按照一般的變量命名規(guī)則.
7.6. 函數(shù)命名
總述
常規(guī)函數(shù)使用大小寫混合, 取值和設(shè)值函數(shù)則要求與變量名匹配:MyExcitingFunction(),MyExcitingMethod(),my_exciting_member_variable(),set_my_exciting_member_variable().
說(shuō)明
一般來(lái)說(shuō), 函數(shù)名的每個(gè)單詞首字母大寫 (即 “駝峰變量名” 或 “帕斯卡變量名”), 沒(méi)有下劃線. 對(duì)于首字母縮寫的單詞, 更傾向于將它們視作一個(gè)單詞進(jìn)行首字母大寫 (例如, 寫作StartRpc()而非StartRPC()).
AddTableEntry()DeleteUrl()OpenFileOrDie()
(同樣的命名規(guī)則同時(shí)適用于類作用域與命名空間作用域的常量, 因?yàn)樗鼈兪亲鳛?API 的一部分暴露對(duì)外的, 因此應(yīng)當(dāng)讓它們看起來(lái)像是一個(gè)函數(shù), 因?yàn)樵谶@時(shí), 它們實(shí)際上是一個(gè)對(duì)象而非函數(shù)的這一事實(shí)對(duì)外不過(guò)是一個(gè)無(wú)關(guān)緊要的實(shí)現(xiàn)細(xì)節(jié).)
取值和設(shè)值函數(shù)的命名與變量一致. 一般來(lái)說(shuō)它們的名稱與實(shí)際的成員變量對(duì)應(yīng), 但并不強(qiáng)制要求. 例如intcount()與voidset_count(intcount).
7.7. 命名空間命名
總述
命名空間以小寫字母命名. 最高級(jí)命名空間的名字取決于項(xiàng)目名稱. 要注意避免嵌套命名空間的名字之間和常見(jiàn)的頂級(jí)命名空間的名字之間發(fā)生沖突.
頂級(jí)命名空間的名稱應(yīng)當(dāng)是項(xiàng)目名或者是該命名空間中的代碼所屬的團(tuán)隊(duì)的名字. 命名空間中的代碼, 應(yīng)當(dāng)存放于和命名空間的名字匹配的文件夾或其子文件夾中.
注意不使用縮寫作為名稱的規(guī)則同樣適用于命名空間. 命名空間中的代碼極少需要涉及命名空間的名稱, 因此沒(méi)有必要在命名空間中使用縮寫.
要避免嵌套的命名空間與常見(jiàn)的頂級(jí)命名空間發(fā)生名稱沖突. 由于名稱查找規(guī)則的存在, 命名空間之間的沖突完全有可能導(dǎo)致編譯失敗. 尤其是, 不要?jiǎng)?chuàng)建嵌套的std命名空間. 建議使用更獨(dú)特的項(xiàng)目標(biāo)識(shí)符 (websearch::index,websearch::index_util) 而非常見(jiàn)的極易發(fā)生沖突的名稱 (比如websearch::util).
對(duì)于internal命名空間, 要當(dāng)心加入到同一internal命名空間的代碼之間發(fā)生沖突 (由于內(nèi)部維護(hù)人員通常來(lái)自同一團(tuán)隊(duì), 因此常有可能導(dǎo)致沖突). 在這種情況下, 請(qǐng)使用文件名以使得內(nèi)部名稱獨(dú)一無(wú)二 (例如對(duì)于frobber.h, 使用websearch::index::frobber_internal).
7.8. 枚舉命名
總述
枚舉的命名應(yīng)當(dāng)和常量或宏一致:kEnumName或是ENUM_NAME.
說(shuō)明
單獨(dú)的枚舉值應(yīng)該優(yōu)先采用常量的命名方式. 但宏方式的命名也可以接受. 枚舉名UrlTableErrors(以及AlternateUrlTableErrors) 是類型, 所以要用大小寫混合的方式.
enum UrlTableErrors { kOK = 0, kErrorOutOfMemory, kErrorMalformedInput,};enum AlternateUrlTableErrors { OK = 0, OUT_OF_MEMORY = 1, MALFORMED_INPUT = 2,};
2009 年 1 月之前, 我們一直建議采用宏的方式命名枚舉值. 由于枚舉值和宏之間的命名沖突, 直接導(dǎo)致了很多問(wèn)題. 由此, 這里改為優(yōu)先選擇常量風(fēng)格的命名方式. 新代碼應(yīng)該盡可能優(yōu)先使用常量風(fēng)格. 但是老代碼沒(méi)必要切換到常量風(fēng)格, 除非宏風(fēng)格確實(shí)會(huì)產(chǎn)生編譯期問(wèn)題.
7.9. 宏命名
總述
你并不打算使用宏, 對(duì)吧? 如果你一定要用, 像這樣命名:MY_MACRO_THAT_SCARES_SMALL_CHILDREN.
說(shuō)明
參考預(yù)處理宏; 通常不應(yīng)該使用宏. 如果不得不用, 其命名像枚舉命名一樣全部大寫, 使用下劃線:
#define ROUND(x) ...#define PI_ROUNDED 3.0
7.10. 命名規(guī)則的特例
總述
如果你命名的實(shí)體與已有 C/C++ 實(shí)體相似, 可參考現(xiàn)有命名策略.
bigopen(): 函數(shù)名, 參照open()的形式
uint:typedef
bigpos:struct或class, 參照pos的形式
sparse_hash_map: STL 型實(shí)體; 參照 STL 命名約定
LONGLONG_MAX: 常量, 如同INT_MAX
譯者(acgtyrant)筆記
感覺(jué) Google 的命名約定很高明, 比如寫了簡(jiǎn)單的類 QueryResult, 接著又可以直接定義一個(gè)變量 query_result, 區(qū)分度很好; 再次, 類內(nèi)變量以下劃線結(jié)尾, 那么就可以直接傳入同名的形參, 比如TextQuery::TextQuery(std::stringword):word_(word){}, 其中word_自然是類內(nèi)私有成員.
8. 注釋
注釋雖然寫起來(lái)很痛苦, 但對(duì)保證代碼可讀性至關(guān)重要. 下面的規(guī)則描述了如何注釋以及在哪兒注釋. 當(dāng)然也要記住: 注釋固然很重要, 但最好的代碼應(yīng)當(dāng)本身就是文檔. 有意義的類型名和變量名, 要遠(yuǎn)勝過(guò)要用注釋解釋的含糊不清的名字.
你寫的注釋是給代碼讀者看的, 也就是下一個(gè)需要理解你的代碼的人. 所以慷慨些吧, 下一個(gè)讀者可能就是你!
8.1. 注釋風(fēng)格
總述
使用//或/**/, 統(tǒng)一就好.
說(shuō)明
//或/**/都可以; 但//更常用. 要在如何注釋及注釋風(fēng)格上確保統(tǒng)一.
8.2. 文件注釋
總述
在每一個(gè)文件開(kāi)頭加入版權(quán)公告.
文件注釋描述了該文件的內(nèi)容. 如果一個(gè)文件只聲明, 或?qū)崿F(xiàn), 或測(cè)試了一個(gè)對(duì)象, 并且這個(gè)對(duì)象已經(jīng)在它的聲明處進(jìn)行了詳細(xì)的注釋, 那么就沒(méi)必要再加上文件注釋. 除此之外的其他文件都需要文件注釋.
說(shuō)明
法律公告和作者信息
每個(gè)文件都應(yīng)該包含許可證引用. 為項(xiàng)目選擇合適的許可證版本.(比如, Apache 2.0, BSD, LGPL, GPL)
如果你對(duì)原始作者的文件做了重大修改, 請(qǐng)考慮刪除原作者信息.
文件內(nèi)容
如果一個(gè).h文件聲明了多個(gè)概念, 則文件注釋應(yīng)當(dāng)對(duì)文件的內(nèi)容做一個(gè)大致的說(shuō)明, 同時(shí)說(shuō)明各概念之間的聯(lián)系. 一個(gè)一到兩行的文件注釋就足夠了, 對(duì)于每個(gè)概念的詳細(xì)文檔應(yīng)當(dāng)放在各個(gè)概念中, 而不是文件注釋中.
不要在.h和.cc之間復(fù)制注釋, 這樣的注釋偏離了注釋的實(shí)際意義.
8.3. 類注釋
總述
每個(gè)類的定義都要附帶一份注釋, 描述類的功能和用法, 除非它的功能相當(dāng)明顯.
// Iterates over the contents of a GargantuanTable.// Example:// GargantuanTableIterator* iter = table->NewIterator();// for (iter->Seek("foo"); !iter->done(); iter->Next()) {// process(iter->key(), iter->value());// }// delete iter;class GargantuanTableIterator { ...};
說(shuō)明
類注釋應(yīng)當(dāng)為讀者理解如何使用與何時(shí)使用類提供足夠的信息, 同時(shí)應(yīng)當(dāng)提醒讀者在正確使用此類時(shí)應(yīng)當(dāng)考慮的因素. 如果類有任何同步前提, 請(qǐng)用文檔說(shuō)明. 如果該類的實(shí)例可被多線程訪問(wèn), 要特別注意文檔說(shuō)明多線程環(huán)境下相關(guān)的規(guī)則和常量使用.
如果你想用一小段代碼演示這個(gè)類的基本用法或通常用法, 放在類注釋里也非常合適.
如果類的聲明和定義分開(kāi)了(例如分別放在了.h和.cc文件中), 此時(shí), 描述類用法的注釋應(yīng)當(dāng)和接口定義放在一起, 描述類的操作和實(shí)現(xiàn)的注釋應(yīng)當(dāng)和實(shí)現(xiàn)放在一起.
8.4. 函數(shù)注釋
總述
函數(shù)聲明處的注釋描述函數(shù)功能; 定義處的注釋描述函數(shù)實(shí)現(xiàn).
說(shuō)明
函數(shù)聲明
基本上每個(gè)函數(shù)聲明處前都應(yīng)當(dāng)加上注釋, 描述函數(shù)的功能和用途. 只有在函數(shù)的功能簡(jiǎn)單而明顯時(shí)才能省略這些注釋(例如, 簡(jiǎn)單的取值和設(shè)值函數(shù)). 注釋使用敘述式 (“Opens the file”) 而非指令式 (“Open the file”); 注釋只是為了描述函數(shù), 而不是命令函數(shù)做什么. 通常, 注釋不會(huì)描述函數(shù)如何工作. 那是函數(shù)定義部分的事情.
函數(shù)聲明處注釋的內(nèi)容:
函數(shù)的輸入輸出.
對(duì)類成員函數(shù)而言: 函數(shù)調(diào)用期間對(duì)象是否需要保持引用參數(shù), 是否會(huì)釋放這些參數(shù).
函數(shù)是否分配了必須由調(diào)用者釋放的空間.
參數(shù)是否可以為空指針.
是否存在函數(shù)使用上的性能隱患.
如果函數(shù)是可重入的, 其同步前提是什么?
舉例如下:
// 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;
但也要避免羅羅嗦嗦, 或者對(duì)顯而易見(jiàn)的內(nèi)容進(jìn)行說(shuō)明. 下面的注釋就沒(méi)有必要加上 “否則返回 false”, 因?yàn)橐呀?jīng)暗含其中了:
// Returns true if the table cannot hold any more entries.bool IsTableFull();
注釋函數(shù)重載時(shí), 注釋的重點(diǎn)應(yīng)該是函數(shù)中被重載的部分, 而不是簡(jiǎn)單的重復(fù)被重載的函數(shù)的注釋. 多數(shù)情況下, 函數(shù)重載不需要額外的文檔, 因此也沒(méi)有必要加上注釋.
注釋構(gòu)造/析構(gòu)函數(shù)時(shí), 切記讀代碼的人知道構(gòu)造/析構(gòu)函數(shù)的功能, 所以 “銷毀這一對(duì)象” 這樣的注釋是沒(méi)有意義的. 你應(yīng)當(dāng)注明的是注明構(gòu)造函數(shù)對(duì)參數(shù)做了什么 (例如, 是否取得指針?biāo)袡?quán)) 以及析構(gòu)函數(shù)清理了什么. 如果都是些無(wú)關(guān)緊要的內(nèi)容, 直接省掉注釋. 析構(gòu)函數(shù)前沒(méi)有注釋是很正常的.
函數(shù)定義
如果函數(shù)的實(shí)現(xiàn)過(guò)程中用到了很巧妙的方式, 那么在函數(shù)定義處應(yīng)當(dāng)加上解釋性的注釋. 例如, 你所使用的編程技巧, 實(shí)現(xiàn)的大致步驟, 或解釋如此實(shí)現(xiàn)的理由. 舉個(gè)例子, 你可以說(shuō)明為什么函數(shù)的前半部分要加鎖而后半部分不需要.
不要從.h文件或其他地方的函數(shù)聲明處直接復(fù)制注釋. 簡(jiǎn)要重述函數(shù)功能是可以的, 但注釋重點(diǎn)要放在如何實(shí)現(xiàn)上.
8.5. 變量注釋
總述
通常變量名本身足以很好說(shuō)明變量用途. 某些情況下, 也需要額外的注釋說(shuō)明.
說(shuō)明
類數(shù)據(jù)成員
每個(gè)類數(shù)據(jù)成員 (也叫實(shí)例變量或成員變量) 都應(yīng)該用注釋說(shuō)明用途. 如果有非變量的參數(shù)(例如特殊值, 數(shù)據(jù)成員之間的關(guān)系, 生命周期等)不能夠用類型與變量名明確表達(dá), 則應(yīng)當(dāng)加上注釋. 然而, 如果變量類型與變量名已經(jīng)足以描述一個(gè)變量, 那么就不再需要加上注釋.
特別地, 如果變量可以接受NULL或-1等警戒值, 須加以說(shuō)明. 比如:
private: // Used to bounds-check table accesses. -1 means // that we don't yet know how many entries the table has. int num_total_entries_;
全局變量
和數(shù)據(jù)成員一樣, 所有全局變量也要注釋說(shuō)明含義及用途, 以及作為全局變量的原因. 比如:
// The total number of tests cases that we run through in this regression test.const int kNumTestCases = 6;
8.6. 實(shí)現(xiàn)注釋
總述
對(duì)于代碼中巧妙的, 晦澀的, 有趣的, 重要的地方加以注釋.
說(shuō)明
代碼前注釋
巧妙或復(fù)雜的代碼段前要加注釋. 比如:
// 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;}
行注釋
比較隱晦的地方要在行尾加入注釋. 在行尾空兩格進(jìn)行注釋. 比如:
// If we have enough memory, mmap the data portion too.mmap_budget = max
注意, 這里用了兩段注釋分別描述這段代碼的作用, 和提示函數(shù)返回時(shí)錯(cuò)誤已經(jīng)被記入日志.
如果你需要連續(xù)進(jìn)行多行注釋, 可以使之對(duì)齊獲得更好的可讀性:
DoSomething(); // Comment here so the comments line up.DoSomethingElseThatIsLonger(); // Two spaces between the code and the comment.{ // One space before comment when opening a new scope is allowed, // thus the comment lines up with the following comments and code. DoSomethingElse(); // Two spaces before line comments normally.}std::vector
函數(shù)參數(shù)注釋
如果函數(shù)參數(shù)的意義不明顯, 考慮用下面的方式進(jìn)行彌補(bǔ):
如果參數(shù)是一個(gè)字面常量, 并且這一常量在多處函數(shù)調(diào)用中被使用, 用以推斷它們一致, 你應(yīng)當(dāng)用一個(gè)常量名讓這一約定變得更明顯, 并且保證這一約定不會(huì)被打破.
考慮更改函數(shù)的簽名, 讓某個(gè)bool類型的參數(shù)變?yōu)閑num類型, 這樣可以讓這個(gè)參數(shù)的值表達(dá)其意義.
如果某個(gè)函數(shù)有多個(gè)配置選項(xiàng), 你可以考慮定義一個(gè)類或結(jié)構(gòu)體以保存所有的選項(xiàng), 并傳入類或結(jié)構(gòu)體的實(shí)例. 這樣的方法有許多優(yōu)點(diǎn), 例如這樣的選項(xiàng)可以在調(diào)用處用變量名引用, 這樣就能清晰地表明其意義. 同時(shí)也減少了函數(shù)參數(shù)的數(shù)量, 使得函數(shù)調(diào)用更易讀也易寫. 除此之外, 以這樣的方式, 如果你使用其他的選項(xiàng), 就無(wú)需對(duì)調(diào)用點(diǎn)進(jìn)行更改.
用具名變量代替大段而復(fù)雜的嵌套表達(dá)式.
萬(wàn)不得已時(shí), 才考慮在調(diào)用點(diǎn)用注釋闡明參數(shù)的意義.
比如下面的示例的對(duì)比:
// What are these arguments?const DecimalNumber product = CalculateProduct(values, 7, false, nullptr);
和
ProductOptions options;options.set_precision_decimals(7);options.set_use_cache(ProductOptions::kDontUseCache);const DecimalNumber product = CalculateProduct(values, options, /*completion_callback=*/nullptr);
哪個(gè)更清晰一目了然.
不允許的行為
不要描述顯而易見(jiàn)的現(xiàn)象,永遠(yuǎn)不要用自然語(yǔ)言翻譯代碼作為注釋, 除非即使對(duì)深入理解 C++ 的讀者來(lái)說(shuō)代碼的行為都是不明顯的. 要假設(shè)讀代碼的人 C++ 水平比你高, 即便他/她可能不知道你的用意:
你所提供的注釋應(yīng)當(dāng)解釋代碼為什么要這么做和代碼的目的, 或者最好是讓代碼自文檔化.
比較這樣的注釋:
// Find the element in the vector. <-- 差: 這太明顯了!auto iter = std::find(v.begin(), v.end(), element);if (iter != v.end()) { Process(element);}
和這樣的注釋:
// Process "element" unless it was already processed.auto iter = std::find(v.begin(), v.end(), element);if (iter != v.end()) { Process(element);}
自文檔化的代碼根本就不需要注釋. 上面例子中的注釋對(duì)下面的代碼來(lái)說(shuō)就是毫無(wú)必要的:
if (!IsAlreadyProcessed(element)) { Process(element);}
8.8. 標(biāo)點(diǎn), 拼寫和語(yǔ)法
總述
注意標(biāo)點(diǎn), 拼寫和語(yǔ)法; 寫的好的注釋比差的要易讀的多.
說(shuō)明
注釋的通常寫法是包含正確大小寫和結(jié)尾句號(hào)的完整敘述性語(yǔ)句. 大多數(shù)情況下, 完整的句子比句子片段可讀性更高. 短一點(diǎn)的注釋, 比如代碼行尾注釋, 可以隨意點(diǎn), 但依然要注意風(fēng)格的一致性.
雖然被別人指出該用分號(hào)時(shí)卻用了逗號(hào)多少有些尷尬, 但清晰易讀的代碼還是很重要的. 正確的標(biāo)點(diǎn), 拼寫和語(yǔ)法對(duì)此會(huì)有很大幫助.
8.8. TODO 注釋
總述
對(duì)那些臨時(shí)的, 短期的解決方案, 或已經(jīng)夠好但仍不完美的代碼使用TODO注釋.
TODO注釋要使用全大寫的字符串TODO, 在隨后的圓括號(hào)里寫上你的名字, 郵件地址, bug ID, 或其它身份標(biāo)識(shí)和與這一TODO相關(guān)的 issue. 主要目的是讓添加注釋的人 (也是可以請(qǐng)求提供更多細(xì)節(jié)的人) 可根據(jù)規(guī)范的TODO格式進(jìn)行查找. 添加TODO注釋并不意味著你要自己來(lái)修正, 因此當(dāng)你加上帶有姓名的TODO時(shí), 一般都是寫上自己的名字.
// TODO(kl@gmail.com): Use a "*" here for concatenation operator.// TODO(Zeke) change this to use relations.// TODO(bug 12345): remove the "Last visitors" feature
如果加TODO是為了在 “將來(lái)某一天做某事”, 可以附上一個(gè)非常明確的時(shí)間 “Fix by November 2005”), 或者一個(gè)明確的事項(xiàng) (“Remove this code when all clients can handle XML responses.”).
8.9. 棄用注釋
總述
通過(guò)棄用注釋(DEPRECATEDcomments)以標(biāo)記某接口點(diǎn)已棄用.
您可以寫上包含全大寫的DEPRECATED的注釋, 以標(biāo)記某接口為棄用狀態(tài). 注釋可以放在接口聲明前, 或者同一行.
在DEPRECATED一詞后, 在括號(hào)中留下您的名字, 郵箱地址以及其他身份標(biāo)識(shí).
棄用注釋應(yīng)當(dāng)包涵簡(jiǎn)短而清晰的指引, 以幫助其他人修復(fù)其調(diào)用點(diǎn). 在 C++ 中, 你可以將一個(gè)棄用函數(shù)改造成一個(gè)內(nèi)聯(lián)函數(shù), 這一函數(shù)將調(diào)用新的接口.
僅僅標(biāo)記接口為DEPRECATED并不會(huì)讓大家不約而同地棄用, 您還得親自主動(dòng)修正調(diào)用點(diǎn)(callsites), 或是找個(gè)幫手.
修正好的代碼應(yīng)該不會(huì)再涉及棄用接口點(diǎn)了, 著實(shí)改用新接口點(diǎn). 如果您不知從何下手, 可以找標(biāo)記棄用注釋的當(dāng)事人一起商量.
譯者 (YuleFox) 筆記
關(guān)于注釋風(fēng)格, 很多 C++ 的 coders 更喜歡行注釋, C coders 或許對(duì)塊注釋依然情有獨(dú)鐘, 或者在文件頭大段大段的注釋時(shí)使用塊注釋;
文件注釋可以炫耀你的成就, 也是為了捅了簍子別人可以找你;
注釋要言簡(jiǎn)意賅, 不要拖沓冗余, 復(fù)雜的東西簡(jiǎn)單化和簡(jiǎn)單的東西復(fù)雜化都是要被鄙視的;
對(duì)于 Chinese coders 來(lái)說(shuō), 用英文注釋還是用中文注釋, it is a problem, 但不管怎樣, 注釋是為了讓別人看懂, 難道是為了炫耀編程語(yǔ)言之外的你的母語(yǔ)或外語(yǔ)水平嗎;
注釋不要太亂, 適當(dāng)?shù)目s進(jìn)才會(huì)讓人樂(lè)意看. 但也沒(méi)有必要規(guī)定注釋從第幾列開(kāi)始 (我自己寫代碼的時(shí)候總喜歡這樣), UNIX/LINUX 下還可以約定是使用 tab 還是 space, 個(gè)人傾向于 space;
TODO 很不錯(cuò), 有時(shí)候, 注釋確實(shí)是為了標(biāo)記一些未完成的或完成的不盡如人意的地方, 這樣一搜索, 就知道還有哪些活要干, 日志都省了.
-
Google
+關(guān)注
關(guān)注
5文章
1789瀏覽量
58860 -
編程
+關(guān)注
關(guān)注
88文章
3687瀏覽量
95072 -
C++
+關(guān)注
關(guān)注
22文章
2119瀏覽量
75038
原文標(biāo)題:Google C++ 編程規(guī)范 - 5
文章出處:【微信號(hào):C_Expert,微信公眾號(hào):C語(yǔ)言專家集中營(yíng)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
MATLAB 編程風(fēng)格指南
Google C++編程指南
MATLAB編程風(fēng)格指南
Google編程風(fēng)格指南(一)
Google編程風(fēng)格指南(二)
Google編程風(fēng)格指南(三)
Google編程風(fēng)格指南(四)
Google編程風(fēng)格指南(六)
Google C++編程風(fēng)格指南PDF版免費(fèi)下載

Google C++編程風(fēng)格指南PDF電子書(shū)免費(fèi)下載

評(píng)論