最重要的一致性規(guī)則是命名管理。命名風(fēng)格快速獲知名字代表的是什么東西:類(lèi)型?變量?函數(shù)?常量?宏…?甚至不需要去查找類(lèi)型聲明。我們大腦中的模式匹配引擎可以非常可靠的處理這些命名規(guī)則。
命名規(guī)則具有一定的隨意性,但相比較個(gè)人喜好命名,一致性更重要。所以不管你怎么想,規(guī)則總是規(guī)則。
函數(shù)命名,變量命名,文件命名要有描述性,少用縮寫(xiě)。
盡可能給有描述性的命名,別心疼空間,畢竟讓代碼易于新讀者理解很重要。不要用只有項(xiàng)目開(kāi)發(fā)者能理解的縮寫(xiě),也不要通過(guò)砍掉幾個(gè)字母來(lái)縮寫(xiě)單詞。
下面給出一些通用原則的示例:
int PRice_count_reader; // 無(wú)縮寫(xiě)int num_errors; // "num"本來(lái)就很常見(jiàn),可以縮寫(xiě)int num_dns_connections; // 人人都知道“DNS”是什么下面的命名規(guī)則盡量避免:
int n; // 莫名其妙int nerr; // 怪縮寫(xiě)int n_comp_conns; // 怪縮寫(xiě)int wgc_connections; // 只有貴團(tuán)隊(duì)知道這是什么東西int pc_reader; // "pc"有太多可能的解釋了int cstmr_id; // 有刪減若干字母文件名要全部小寫(xiě),可以包含下劃線(xiàn)(_)或者連字符(-),按照項(xiàng)目約定來(lái)。如果沒(méi)有項(xiàng)目約定,則“_”更好。可以接受的文件命名:
* my_useful_class.cc* my-useful-class.cc* myusefulclass.cc* myusefulclass_test.cc // "_unittest"和"_regtest"已經(jīng)棄用C++文件要以.cc
結(jié)尾(為什么不是.cpp
呢?)。頭文件以.h結(jié)尾。專(zhuān)門(mén)插入文本的文件則以.inc
結(jié)尾,參見(jiàn)關(guān)于頭文件的規(guī)則。
不要使用已經(jīng)存在于/usr/include
下的文件名(即編譯器搜索系統(tǒng)頭文件的路徑),如db.h
。
通常應(yīng)盡量讓文件名更加明確。http/_server/_logs.h
就比logs.h
要好。定義類(lèi)時(shí)文件名一般成對(duì)出現(xiàn),如foo/_bar.h
和foo/_bar.cc
,對(duì)應(yīng)于類(lèi)FooBar
。
內(nèi)聯(lián)函數(shù)必須放在.h
文件中,如果內(nèi)聯(lián)函數(shù)比較短, 就直接放在.h
中。
類(lèi)型名稱(chēng)的每個(gè)單詞首字母均大寫(xiě),不包含下劃線(xiàn):MyExcitingClass
,MyExcitingEnum
。
所有類(lèi)型命名——類(lèi),結(jié)構(gòu)體,類(lèi)型定義(typedef),枚舉——均使用相同約定。例如:
// classes and structsclass UrlTable { ...class UrlTableTester { ...struct UrlTableProperties { ...// typedefstypedef hash_map<UrlTableProperties*, string> PropertiesMap;// enumsenum UrlTableErrors { ...變量名一律小寫(xiě),單詞之間用下劃線(xiàn)連接。類(lèi)的成員變量以下劃線(xiàn)結(jié)尾,但結(jié)構(gòu)體的就不用。例如:a_local_variable, a_struct_data_member, a_class_data_member_。
普通變量命名的舉例:
string table_name; // 可以——用下劃線(xiàn)string tablename; // 可以——全小寫(xiě)string tableName; // 差——混合大小寫(xiě)(但這似乎是java的命名規(guī)則?)類(lèi)數(shù)據(jù)成員:
不管是靜態(tài)的還是非靜態(tài)的,類(lèi)數(shù)據(jù)成員都可以和普通變量一樣,彈藥接下劃線(xiàn)。class TableInfo {...private: string table_name_; // 可以——尾后加下劃線(xiàn) string tablename_; // 可以 static Pool<TableInfo>* pool_; // 可以};結(jié)構(gòu)體變量:
不管是靜態(tài)的還是非靜態(tài)的,結(jié)構(gòu)體數(shù)據(jù)成員都可以和普通變量一樣,不用像類(lèi)那樣接下劃線(xiàn)。結(jié)構(gòu)體與類(lèi)的討論請(qǐng)參考 結(jié)構(gòu)體vs. 類(lèi) 一節(jié)。struct UrlTableProperties { string name; int num_entries;}全局變量:
對(duì)全局變量沒(méi)有特別要求,少用就好,但如果你要用,可以用g_或其它標(biāo)志作為前綴,以便更好的區(qū)分局部變量。在全局或者類(lèi)里的常量名稱(chēng)前加k:kDaysInAWeek。且除去開(kāi)頭的k之外每個(gè)單詞開(kāi)頭字母均大寫(xiě)。
所有編譯時(shí)常量,無(wú)論是局部的,全局的還是類(lèi)中的,和其他變量稍微區(qū)別一下。k后接大寫(xiě)字母開(kāi)頭的單詞。這規(guī)則也適用于編譯時(shí)的局部作用域常量,不過(guò)要按變量規(guī)則來(lái)命名也可以。
const int kDaysInAWeek = 7;常規(guī)函數(shù)使用大小寫(xiě)混合,取值和設(shè)置函數(shù)則要求與變量名匹配:MyExcitingFunction(), MyExcitingMethod(), my_exciting_member_variable(), set_my_exciting_member_variable()。
常規(guī)函數(shù):
函數(shù)名的每個(gè)單詞首字母大寫(xiě),沒(méi)有下劃線(xiàn)。如果您的某函數(shù)出錯(cuò)時(shí)就要直接crash,那么就在函數(shù)名加上OrDie,但這函數(shù)本身必須集成在產(chǎn)品代碼里,且平時(shí)也可能會(huì)出錯(cuò)。AddTableEntry()DeleteUrl()OpenFileOrDie()取值和設(shè)值函數(shù):
取值(accessors)和設(shè)值(Mutators)函數(shù)要與存取的變量名匹配。這兒摘錄一個(gè)類(lèi),num_entries_是該類(lèi)的實(shí)例變量:class MyClass {public: ... int num_entries() const { return num_entries_; } void set_num_entries(int num_entries) { num_entries_ = num_entries; }private: int num_entries_;};其它非常短小的內(nèi)聯(lián)函數(shù)名也可以用小寫(xiě)字母,例如,如果你在循環(huán)中調(diào)用這樣的函數(shù)甚至都不用緩存器返回值,小寫(xiě)命名就可以接受。名字空間用小寫(xiě)字母命名,并基于項(xiàng)目名稱(chēng)和目錄結(jié)構(gòu):google_awesome_project。
關(guān)于名字空間的討論和如何命名,參考 名字空間 一節(jié)。
枚舉的命名應(yīng)當(dāng)和常量或者宏一致:kEnumName或者ENUM_NAME。
單獨(dú)的枚舉值應(yīng)該優(yōu)先蠶蛹常量的命名方式,但宏方式的命名也可以接受。枚舉名UrlTableErrors(以及AlternateUrlTableErrors)是類(lèi)型,所以要用大小寫(xiě)混合的方式。
enum UrlTableErrors { kOK = 0, kErrorOutOfMemory, kErrorMalformatedInput,};enum AlternateUrlTableErrors { OK = 0, OUT_OF_MEMORY = 1, MALFORMATED_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)題。
你并不打算使用宏,對(duì)吧?如果你一定要用,像這樣命名:MY_MACRO_THAT_SCARES_SMALL_CHILDREN。
參考預(yù)處理宏。通常不應(yīng)該使用宏,如果不得不用,其命名像枚舉命名一樣全部大寫(xiě),使用下劃線(xiàn):
#define ROUND(X) ...#define PI_ROUNDED 3.0如果你命名的實(shí)體與已有的C/C++實(shí)體相似,可參考現(xiàn)有命名策略。
bigopen(); // 函數(shù)名,參照open()的形式uint:bigpos: // struct或者class,參照pos的形式sparse_hash_map: // STL相似實(shí)體,參照STL命名約定LONGLONG_MAX: // 常量,如同INT_MAXTextQuery::TextQuery(std::string Word) : word/_(word) {}
,其中word_自然是類(lèi)內(nèi)私有成員。但是Google的命名規(guī)則也并不是完美的。事實(shí)上。例如在類(lèi)內(nèi)對(duì)于存取函數(shù)和其它函數(shù)采用不同的命名規(guī)則,會(huì)有時(shí)候令人迷惑(個(gè)人體驗(yàn))。其它命名規(guī)則也有其好處。例如CGAL類(lèi)庫(kù)中的命名規(guī)則我覺(jué)得就有如下好處:1)類(lèi)成員變量以m_XX命名,在編程時(shí)只要打出m_,編輯器就可以自動(dòng)彈出所有類(lèi)成員變量可供選擇;2)指針變量以pXXX開(kāi)始,使人一看就知道該變量是指針類(lèi)型的,而Google命名規(guī)則中沒(méi)有區(qū)分指針變量和非指針變量;3)類(lèi)成員函數(shù)的命名中單詞之間以下劃線(xiàn)分開(kāi),讓人更容易看清(Google的命名規(guī)則中,如果函數(shù)名很長(zhǎng),需要讀者仔細(xì)去辨認(rèn)單詞的組成,進(jìn)而推斷函數(shù)的作用)。新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注