日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > c/c++ >内容正文

c/c++

【代码规范】google开源c\c++项目代码规范

發(fā)布時(shí)間:2024/4/18 c/c++ 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【代码规范】google开源c\c++项目代码规范 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
版權(quán)聲明:版權(quán)聲明:本文為博主原創(chuàng)文章,未經(jīng)博主允許不得轉(zhuǎn)載;https://blog.csdn.net/csdn_baotai https://blog.csdn.net/csdn_baotai/article/details/80304636 </div><link rel="stylesheet" href="https://csdnimg.cn/release/phoenix/template/css/ck_htmledit_views-d7e2a68c7c.css"><div class="htmledit_views" id="content_views"><h1 style="margin-top:0px;background-color:rgb(242,242,242);"><a name="t0"></a><span style="font-family:'Microsoft YaHei';font-size:24px;color:#339999;"><span style="vertical-align:inherit;"><span style="vertical-align:inherit;"><span style="vertical-align:inherit;"><span style="vertical-align:inherit;">google開(kāi)源</span></span></span></span><span style="vertical-align:inherit;"><span style="vertical-align:inherit;"> C / C ++項(xiàng)目代碼規(guī)范</span></span></span></h1><h1 style="margin-top:0px;color:rgb(64,64,64);background-color:rgb(242,242,242);"><a name="t1"></a><span style="vertical-align:inherit;"><span style="font-family:'Microsoft YaHei';vertical-align:inherit;">1.頭文件</span></span></h1><p style="line-height:24px;margin-bottom:24px;color:rgb(64,64,64);background-color:rgb(242,242,242);"><span style="font-family:'Microsoft YaHei';"><span style="vertical-align:inherit;"><span style="vertical-align:inherit;">每通常一個(gè)&nbsp; </span></span><code class="docutils literal" style="font-size:12.8px;white-space:nowrap;max-width:100%;background:rgb(242,242,242);border:1px solid rgb(225,228,229);padding:2px 5px;color:rgb(231,76,60);"><span class="pre">.cc</span></code><span style="vertical-align:inherit;"><span style="vertical-align:inherit;">&nbsp;文件都有一個(gè)對(duì)應(yīng)的&nbsp; </span></span><code class="docutils literal" style="font-size:12.8px;white-space:nowrap;max-width:100%;background:rgb(242,242,242);border:1px solid rgb(225,228,229);padding:2px 5px;color:rgb(231,76,60);"><span class="pre">.h</span></code><span style="vertical-align:inherit;"><span style="vertical-align:inherit;">&nbsp;文件。</span><span style="vertical-align:inherit;">也有一些常見(jiàn)例外,如單元測(cè)試代碼和只包含&nbsp; </span></span><code class="docutils literal" style="font-size:12.8px;white-space:nowrap;max-width:100%;background:rgb(242,242,242);border:1px solid rgb(225,228,229);padding:2px 5px;color:rgb(231,76,60);"><span class="pre">main()</span></code><span style="vertical-align:inherit;"><span style="vertical-align:inherit;">&nbsp;函數(shù)的&nbsp; </span></span><code class="docutils literal" style="font-size:12.8px;white-space:nowrap;max-width:100%;background:rgb(242,242,242);border:1px solid rgb(225,228,229);padding:2px 5px;color:rgb(231,76,60);"><span class="pre">.cc</span></code><span style="vertical-align:inherit;"><span style="vertical-align:inherit;">&nbsp;文件。</span></span></span></p><p style="line-height:24px;margin-bottom:24px;color:rgb(64,64,64);background-color:rgb(242,242,242);"><span style="vertical-align:inherit;"><span style="font-family:'Microsoft YaHei';vertical-align:inherit;">正確使用頭文件可令代碼在可讀性,文件大小和性能上大為改觀。</span></span></p><p style="line-height:24px;margin-bottom:24px;color:rgb(64,64,64);background-color:rgb(242,242,242);"><span style="vertical-align:inherit;"><span style="font-family:'Microsoft YaHei';vertical-align:inherit;">下面的規(guī)則將引導(dǎo)你規(guī)避使用頭文件時(shí)的各種陷阱。</span></span></p><div class="section" style="color:rgb(64,64,64);background-color:rgb(242,242,242);"><span style="font-family:'Microsoft YaHei';"><span></span></span><h2 style="margin-top:0px;"><a name="t2"></a><span style="font-family:'Microsoft YaHei';vertical-align:inherit;"><span style="vertical-align:inherit;">1.1。</span><span style="vertical-align:inherit;">自包含的頭文件</span></span></h2><div class="admonition tip" style="padding:12px;line-height:24px;margin-bottom:24px;background:rgb(219,250,244);"><p class="first admonition-title" style="line-height:1;margin:-12px -12px 12px;font-weight:bold;color:rgb(255,255,255);background:rgb(26,188,156);padding:6px 12px;"><span style="vertical-align:inherit;"><span style="font-family:'Microsoft YaHei';vertical-align:inherit;">TIP</span></span></p><p class="last" style="line-height:24px;margin-bottom:0px;"><span style="font-family:'Microsoft YaHei';"><span style="vertical-align:inherit;"><span style="vertical-align:inherit;">頭文件應(yīng)該能夠自給自足(自包含的,也就是可以作為第一個(gè)頭文件被引入</span><span style="vertical-align:inherit;">),以&nbsp; </span></span><code class="docutils literal" style="font-size:12.8px;white-space:nowrap;max-width:100%;background:rgb(242,242,242);border:1px solid rgb(225,228,229);padding:2px 5px;color:rgb(231,76,60);"><span class="pre">.h</span></code><span style="vertical-align:inherit;"><span style="vertical-align:inherit;">&nbsp;結(jié)尾。至于用來(lái)插入文本的文件,說(shuō)到底它們并不是頭文件,所以以應(yīng)&nbsp; </span></span><code class="docutils literal" style="font-size:12.8px;white-space:nowrap;max-width:100%;background:rgb(242,242,242);border:1px solid rgb(225,228,229);padding:2px 5px;color:rgb(231,76,60);"><span class="pre">.inc</span></code><span style="vertical-align:inherit;"><span style="vertical-align:inherit;">&nbsp;結(jié)尾不允許。出分離&nbsp; </span></span><code class="docutils literal" style="font-size:12.8px;white-space:nowrap;max-width:100%;background:rgb(242,242,242);border:1px solid rgb(225,228,229);padding:2px 5px;color:rgb(231,76,60);"><span class="pre">-inl.h</span></code><span style="vertical-align:inherit;"><span style="vertical-align:inherit;">&nbsp;頭文件的做法。</span></span></span></p></div><p style="line-height:24px;margin-bottom:24px;"><span style="font-family:'Microsoft YaHei';"><span style="vertical-align:inherit;"><span style="vertical-align:inherit;">所有頭文件要能夠自給自足。換言之,用戶和重構(gòu)工具不需要為特別場(chǎng)合而包含額外的頭文件。詳言之,一個(gè)頭文件要有&nbsp; </span></span><a class="reference internal" href="http://zh-google-styleguide.readthedocs.io/en/latest/google-cpp-styleguide/headers/#define-guard" rel="nofollow" style="color:rgb(155,89,182);" target="_blank"><span style="vertical-align:inherit;"><span style="vertical-align:inherit;">1.2。</span><span style="vertical-align:inherit;">#define保護(hù)</span></span></a><span style="vertical-align:inherit;"><span style="vertical-align:inherit;">,統(tǒng)計(jì)包含它所需要的其它頭文件,也不要求定義任何特別的符號(hào)。</span></span></span></p><p style="line-height:24px;margin-bottom:24px;"><span style="font-family:'Microsoft YaHei';"><span style="vertical-align:inherit;"><span style="vertical-align:inherit;">不過(guò)有一個(gè)例外,即一個(gè)文件并不是自足的,而是作為文本插入到代碼某處。或者,文件內(nèi)容實(shí)際上是其它頭文件的特定平臺(tái)</span><span style="vertical-align:inherit;">(特定于平臺(tái))擴(kuò)展部分,這些文件就要用&nbsp; </span></span><code class="docutils literal" style="font-size:12.8px;white-space:nowrap;max-width:100%;background:rgb(242,242,242);border:1px solid rgb(225,228,229);padding:2px 5px;color:rgb(231,76,60);"><span class="pre">.inc</span></code><span style="vertical-align:inherit;"><span style="vertical-align:inherit;">&nbsp;文件擴(kuò)展名。</span></span></span></p><p style="line-height:24px;margin-bottom:24px;"><span style="font-family:'Microsoft YaHei';"><span style="vertical-align:inherit;"><span style="vertical-align:inherit;">如果&nbsp; </span></span><code class="docutils literal" style="font-size:12.8px;white-space:nowrap;max-width:100%;background:rgb(242,242,242);border:1px solid rgb(225,228,229);padding:2px 5px;color:rgb(231,76,60);"><span class="pre">.h</span></code><span style="vertical-align:inherit;"><span style="vertical-align:inherit;">&nbsp;文件聲明了一個(gè)模板或內(nèi)聯(lián)函數(shù)</span><span style="vertical-align:inherit;">,同時(shí)也在該文件加以定義。有用凡是到這些的&nbsp; </span></span><code class="docutils literal" style="font-size:12.8px;white-space:nowrap;max-width:100%;background:rgb(242,242,242);border:1px solid rgb(225,228,229);padding:2px 5px;color:rgb(231,76,60);"><span class="pre">.cc</span></code><span style="vertical-align:inherit;"><span style="vertical-align:inherit;">&nbsp;文件,就得統(tǒng)統(tǒng)包含該頭文件,否則程序可能會(huì)在構(gòu)建中鏈接失敗</span><span style="vertical-align:inherit;">。不要把這些定義放到分離的&nbsp; </span></span><code class="docutils literal" style="font-size:12.8px;white-space:nowrap;max-width:100%;background:rgb(242,242,242);border:1px solid rgb(225,228,229);padding:2px 5px;color:rgb(231,76,60);"><span class="pre">-inl.h</span></code><span style="vertical-align:inherit;"><span style="vertical-align:inherit;">&nbsp;文件里(譯者注:過(guò)去該規(guī)范曾提倡把定義放到-inl.h里過(guò))。</span></span></span></p><p style="line-height:24px;margin-bottom:24px;"><span style="font-family:'Microsoft YaHei';"><span style="vertical-align:inherit;"><span style="vertical-align:inherit;">有個(gè)例外:如果某函數(shù)模板為所有相關(guān)模板參數(shù)顯式實(shí)例化</span><span style="vertical-align:inherit;">,或本身就是某類(lèi)的一個(gè)私有成員,它就那么定義只能在實(shí)例化該模板的&nbsp; </span></span><code class="docutils literal" style="font-size:12.8px;white-space:nowrap;max-width:100%;background:rgb(242,242,242);border:1px solid rgb(225,228,229);padding:2px 5px;color:rgb(231,76,60);"><span class="pre">.cc</span></code><span style="vertical-align:inherit;"><span style="vertical-align:inherit;">&nbsp;文件里。</span></span></span></p></div><div class="section" style="color:rgb(64,64,64);background-color:rgb(242,242,242);"><span style="font-family:'Microsoft YaHei';"><span></span></span><h2 style="margin-top:0px;"><a name="t3"></a><span style="font-family:'Microsoft YaHei';vertical-align:inherit;"><span style="vertical-align:inherit;">1.2。</span><span style="vertical-align:inherit;">#define保護(hù)</span></span></h2><div class="admonition tip" style="padding:12px;line-height:24px;margin-bottom:24px;background:rgb(219,250,244);"><p class="first admonition-title" style="line-height:1;margin:-12px -12px 12px;font-weight:bold;color:rgb(255,255,255);background:rgb(26,188,156);padding:6px 12px;"><span style="vertical-align:inherit;"><span style="font-family:'Microsoft YaHei';vertical-align:inherit;">TIP</span></span></p><p class="last" style="line-height:24px;margin-bottom:0px;"><span style="font-family:'Microsoft YaHei';"><span style="vertical-align:inherit;"><span style="vertical-align:inherit;">所有頭文件都應(yīng)該使用&nbsp; </span></span><code class="docutils literal" style="font-size:12.8px;white-space:nowrap;max-width:100%;background:rgb(242,242,242);border:1px solid rgb(225,228,229);padding:2px 5px;color:rgb(231,76,60);"><span class="pre">#define</span></code><span style="vertical-align:inherit;"><span style="vertical-align:inherit;">&nbsp;來(lái)防止頭文件被多重包含,命名格式當(dāng)是:&nbsp; </span></span><code class="docutils literal" style="font-size:12.8px;white-space:nowrap;max-width:100%;background:rgb(242,242,242);border:1px solid rgb(225,228,229);padding:2px 5px;color:rgb(231,76,60);"><span class="pre">&lt;PROJECT&gt;_&lt;PATH&gt;_&lt;FILE&gt;_H_</span></code><span style="vertical-align:inherit;"><span style="vertical-align:inherit;">&nbsp;。</span></span></span></p></div><p style="line-height:24px;margin-bottom:24px;"><span style="font-family:'Microsoft YaHei';"><span style="vertical-align:inherit;"><span style="vertical-align:inherit;">為保證唯一性,頭文件的命名應(yīng)該基于所有項(xiàng)目源代碼樹(shù)的全路徑。</span><span style="vertical-align:inherit;">例如,項(xiàng)目&nbsp; </span></span><code class="docutils literal" style="font-size:12.8px;white-space:nowrap;max-width:100%;background:rgb(242,242,242);border:1px solid rgb(225,228,229);padding:2px 5px;color:rgb(231,76,60);"><span class="pre">foo</span></code><span style="vertical-align:inherit;"><span style="vertical-align:inherit;">&nbsp;中的頭文件&nbsp; </span></span><code class="docutils literal" style="font-size:12.8px;white-space:nowrap;max-width:100%;background:rgb(242,242,242);border:1px solid rgb(225,228,229);padding:2px 5px;color:rgb(231,76,60);"><span class="pre">foo/src/bar/baz.h</span></code><span style="vertical-align:inherit;"><span style="vertical-align:inherit;">&nbsp;可按如下方式保護(hù):</span></span></span></p><div class="highlight-c++" style="border:1px solid rgb(225,228,229);padding:0px;margin:1px 0px 24px;"><div class="highlight" style="border:none;padding:0px;margin:0px;"><pre style="margin-bottom:0px;padding:12px;line-height:normal;"><span style="font-family:'Microsoft YaHei';"><span class="cp"><span style="vertical-align:inherit;"><span style="vertical-align:inherit;">#ifndef FOO_BAR_BAZ_H_ </span></span></span>

#define FOO_BAR_BAZ_H_

#endif // FOO_BAR_BAZ_H_

1.3。前置聲明

TIP

盡可能地避免使用前置聲明。使用? #include?所有游戲需要的頭文件即可。

定義:

所謂「前置聲明」(forward declaration)是類(lèi),函數(shù)和模板的純粹聲明,沒(méi)伴隨著其定義。

優(yōu)點(diǎn):

  • 前置聲明能夠節(jié)省編譯時(shí)間,的多余? #include?會(huì)迫使compile-器展開(kāi)更多的文件,處理更多的輸入。
  • 前置聲明能夠節(jié)省不必要的重新編譯的時(shí)間。? #include?使代碼因?yàn)轭^文件中無(wú)關(guān)的改動(dòng)而被重新編譯多次。

缺點(diǎn):

  • 前置聲明隱藏了依賴關(guān)系,頭文件改動(dòng)時(shí),用戶的代碼會(huì)跳過(guò)必要的重新編譯過(guò)程。

  • 前置聲明可能會(huì)被庫(kù)的后續(xù)更改所破壞。前置聲明函數(shù)或模板有時(shí)會(huì)妨礙頭文件開(kāi)發(fā)者變動(dòng)其API。例如擴(kuò)大形參類(lèi)型,加個(gè)自帶默認(rèn)參數(shù)的模板形參等等。

  • 前置聲明來(lái)自命名空間? std::?的符號(hào)時(shí),其行為未定義。

  • 很難判斷什么時(shí)候該用前置聲明,時(shí)候什么用該? #include?極端情況下,用前置聲明代替。? includes?甚至都會(huì)暗暗地改變代碼的含義:

    // bh:
    struct B {};
    struct D B {}

// good_user.cc:
#包括 “BH”
void f B * );
void f void * );
void test D * x { f x ); } //調(diào)用f(B )

如果? #include?被? B?狀語(yǔ)從句:? D?的前置聲明替代,? test()?就會(huì)調(diào)用? f(void)?。
  • 前置聲明了include?不少來(lái)自頭文件的符號(hào)時(shí),就會(huì)比單單一行的? 冗長(zhǎng)。
  • 僅僅為了能前置聲明而重構(gòu)代碼(比如用指針成員代替對(duì)象成員)會(huì)使代碼變得更慢更復(fù)雜。

結(jié)論:

  • 盡量避免前置聲明那些定義在其他項(xiàng)目中的實(shí)體。
  • 函數(shù):總是使用? #include
  • 類(lèi)模板:優(yōu)先使用? #include

至于什么時(shí)候包含頭文件,參見(jiàn)? 1.5。#include的路徑及順序 ?。

1.4。內(nèi)聯(lián)函數(shù)

TIP

只有當(dāng)函數(shù)只有10行甚至更少時(shí)才將其定義為內(nèi)聯(lián)函數(shù)。

定義:

當(dāng)函數(shù)被聲明為內(nèi)聯(lián)函數(shù)之后,編譯器會(huì)將其內(nèi)聯(lián)展開(kāi),而不是按通常的函數(shù)調(diào)用機(jī)制進(jìn)行調(diào)用。

優(yōu)點(diǎn):

只要內(nèi)聯(lián)的函數(shù)體小小,內(nèi)聯(lián)該函數(shù)可以令目標(biāo)代碼更加高效。對(duì)于存取函數(shù)以及其它函數(shù)體比較短,性??能關(guān)鍵的函數(shù),鼓勵(lì)使用內(nèi)聯(lián)。

缺點(diǎn):

濫用內(nèi)聯(lián)將導(dǎo)致程序變得更慢。內(nèi)聯(lián)可能使目標(biāo)代碼量或增或減,這取決于內(nèi)聯(lián)函數(shù)的大小。內(nèi)聯(lián)非常短小的存取函數(shù)通常會(huì)減少代碼大小,但內(nèi)聯(lián)一個(gè)相當(dāng)大的函數(shù)將戲劇性的增加代碼大小。現(xiàn)代處理器由于更好的利用了指令緩存,小巧的代碼往往執(zhí)行更快。

結(jié)論:

一個(gè)較為合理的經(jīng)驗(yàn)準(zhǔn)則是,不要內(nèi)聯(lián)超過(guò)10行的函數(shù)。謹(jǐn)謹(jǐn)對(duì)待析構(gòu)函數(shù),析構(gòu)函數(shù)往往比其表面看起來(lái)要更長(zhǎng),因?yàn)橛须[含的成員和基類(lèi)析構(gòu)函數(shù)被調(diào)用!

另一個(gè)實(shí)用的經(jīng)驗(yàn)準(zhǔn)則:內(nèi)聯(lián)那些包含循環(huán)或? switch?語(yǔ)句的函數(shù)常常是得不償失(除非在大多數(shù)情況下,這些循環(huán)或? switch?語(yǔ)句從不被執(zhí)行)。

有些函數(shù)即使聲明為內(nèi)聯(lián)的也不一定會(huì)被編譯器內(nèi)聯(lián),這點(diǎn)很重要; 比如虛函數(shù)和遞歸函數(shù)就不會(huì)被正常內(nèi)聯(lián)。通常,遞歸函數(shù)不應(yīng)該聲明成內(nèi)聯(lián)函數(shù)。(YuleFox注:遞歸調(diào)用堆棧的展開(kāi)并不像循環(huán)那么簡(jiǎn)單,比如遞進(jìn)層數(shù)在編譯時(shí)可能是未知的,大多數(shù)編譯器都不支持內(nèi)聯(lián)遞歸函數(shù))。虛函數(shù)內(nèi)聯(lián)的主要原因是想把它的函數(shù)體放在類(lèi)定義內(nèi),為了圖個(gè)方便,抑或是當(dāng)作文件描述其行為,比如精短的存取函數(shù)。

1.5。? #include?的路徑及順序

TIP

使用標(biāo)準(zhǔn)的頭文件包含順序可增強(qiáng)可讀性,避免隱藏依賴:相關(guān)頭文件,C庫(kù),C ++庫(kù),其他庫(kù)的? .h,本項(xiàng)目?jī)?nèi)的? .h。

項(xiàng)目?jī)?nèi)部文件應(yīng)按照項(xiàng)目源代碼目錄樹(shù)結(jié)構(gòu)排列,避免使用UNIX特殊的快捷目錄? .(當(dāng)前目錄)或? ?(上級(jí)目錄)。例如,? google-awesome-project/src/base/logging.h?應(yīng)該按如下方式包含:

#include “base / logging.h”

又如,? dir/foo.cc?或? dir/foo_test.cc?的主要作用英文的英文實(shí)現(xiàn)或測(cè)試? dir2/foo2.h?的功能,? foo.cc?中包含頭文件的次序如下:

  • dir2/foo2.h?(優(yōu)先位置,詳情如下)
  • C系統(tǒng)文件
  • C ++系統(tǒng)文件
  • 庫(kù)其他的? .h?文件
  • 項(xiàng)目本。內(nèi)? .h?文件
  • 優(yōu)先這種順序的排序保證當(dāng)? dir2/foo2.h?遺漏某些必要的庫(kù)時(shí),? dir/foo.cc?或? dir/foo_test.cc?的構(gòu)建會(huì)立刻中止。因此這一條規(guī)則保證維護(hù)這些文件的人們首先看到構(gòu)建中止的消息而不是維護(hù)其他包的人們。

    dir/foo.cc?和? dir2/foo2.h?通常位于同一目錄下(如? base/basictypes_unittest.cc?和? base/basictypes.h),但也可放在不同目錄下。

    按字母順序分別對(duì)每種類(lèi)型的頭文件進(jìn)行二次排序是不錯(cuò)的主意。注意較老的代碼可不符合這條規(guī)則,要在方便的時(shí)候改正它們。

    您所依賴的符號(hào)(符號(hào))被哪些頭文件所定義,您就應(yīng)該包含(包括)哪些頭文件,前置聲明 ?(向前聲明)情況除外。您比如要用到? bar.h?中的某個(gè)符號(hào),哪怕您所包含的? foo.h?已經(jīng)包含了? bar.h,也照樣得包含? bar.h,除非foo.h?有明確? 說(shuō)明它會(huì)自動(dòng)向您提供? bar.h?中符號(hào)。不過(guò),凡是cc文件所對(duì)應(yīng)的「相關(guān)頭文件」已經(jīng)包含的,就不用再重復(fù)包含進(jìn)其cc文件里面了,就像? foo.cc?只包含? foo.h就夠了,不用再管后者所包含的其它內(nèi)容。

    #include “foo / public / fooserver.h”//優(yōu)先位置

    #include “foo / public / bar.h”例如,???google-awesome-project/src/foo/internal/fooserver.cc?包含次序如下:

    4.函數(shù)

    4.1。參數(shù)順序

    總述

    函數(shù)的參數(shù)順序?yàn)?#xff1a;輸入?yún)?shù)在先,后跟輸出參數(shù)。

    說(shuō)明

    C / C ++中的函數(shù)參數(shù)或者是函數(shù)的輸入,或者是函數(shù)的輸出,或兼而有之。輸入?yún)?shù)通常是值參或? const?引用,輸出參數(shù)或輸入/輸出參數(shù)則一般為非? const?指針。在排列參數(shù)順序時(shí),將所有的輸入?yún)?shù)置于輸出參數(shù)之前。特別要注意,在加入新參數(shù)時(shí)不要因?yàn)樗鼈兪切聟?shù)就置于參數(shù)列表最后,而是仍然要按照前述的規(guī)則,即將新的輸入?yún)?shù)也置于輸出參數(shù)之前。

    這并非一個(gè)硬性規(guī)定。輸入/輸出參數(shù)(通常是類(lèi)或結(jié)構(gòu)體)讓這個(gè)問(wèn)題變得復(fù)雜。并且,有時(shí)候?yàn)榱似渌瘮?shù)保持一致,你可能不得不不所有變通。

    4.2。編寫(xiě)簡(jiǎn)短函數(shù)

    總述

    我們傾向于編寫(xiě)簡(jiǎn)短,凝練的函數(shù)。

    說(shuō)明

    我們承認(rèn)長(zhǎng)函數(shù)有時(shí)是合理的,因此并不硬限制函數(shù)的長(zhǎng)度。如果函數(shù)超過(guò)40行,可以思索一下能不能在不影響程序結(jié)構(gòu)的前提下對(duì)其進(jìn)行分割。

    即使一個(gè)長(zhǎng)函數(shù)現(xiàn)在工作的非常好,一旦有人對(duì)其修改,有可能出現(xiàn)新的問(wèn)題,甚至導(dǎo)致難以發(fā)現(xiàn)的錯(cuò)誤。使函數(shù)盡量簡(jiǎn)短,以便于他在他人閱讀和修改代碼。

    在處理代碼時(shí),你可能會(huì)發(fā)現(xiàn)復(fù)雜的長(zhǎng)函數(shù)。不要害怕修改現(xiàn)有代碼:如果證實(shí)這些代碼使用/調(diào)試起來(lái)很困難,或者你只需??要使用其中的一小段代碼,考慮將其分割為更加簡(jiǎn)短并易于管理的若干函數(shù)。

    4.3。引用參數(shù)

    總述

    所有按引用傳遞的參數(shù)必須加上? const

    定義

    在C語(yǔ)言中,如果函數(shù)需要修改變量的值,參數(shù)必須為指針,如? 。在C ++中,函數(shù)還可以聲明為引用參數(shù):? 。int?foo(int?pval)int?foo(int?&val)

    優(yōu)點(diǎn)

    引用定義參數(shù)可以防止出現(xiàn)? (pval)++?這樣丑陋的代碼。引用參數(shù)對(duì)于拷貝構(gòu)造函數(shù)這樣的應(yīng)用也是必需的。同時(shí)也更明確地不接受空指針。

    缺點(diǎn)

    容易引起誤解,因?yàn)橐迷谡Z(yǔ)法上是值變量卻擁有指針的語(yǔ)義。

    結(jié)論

    函數(shù)參數(shù)列表中,所有引用參數(shù)都必須是? const

    void Foo const string in string out );

    事實(shí)上這在Google Code是一個(gè)硬性約定:輸入?yún)?shù)是值參或? const?引用,輸出參數(shù)為指針。輸入?yún)?shù)可以是? const?指針,但決不能是非? const?引用參數(shù),除非特殊要求,比如? swap()

    有時(shí)候,在輸入形參中用針指? ?比? ?更明智。比如:const?Tconst?T&

    • 可能會(huì)傳遞空指針。
    • 函數(shù)要把指針或?qū)Φ刂返囊觅x值給輸入形參。

    總而言之,大多時(shí)候輸入形參往往是? 。用若? ?則說(shuō)明輸入側(cè)另有處理。所以若要使用? ,則應(yīng)給出相應(yīng)的理由,否則會(huì)使讀者感到迷惑。const?T&const?T*const?T*

    4.4。函數(shù)重載

    總述

    若要使用函數(shù)重載,則必須能讓讀者一看調(diào)用點(diǎn)就胸有成竹,而不用花心思猜測(cè)調(diào)用的重載函數(shù)到底是哪一種。這一規(guī)則也適用于構(gòu)造函數(shù)。

    定義

    你可以編寫(xiě)一個(gè)參數(shù)類(lèi)型為? ?的函數(shù),然后用另一個(gè)參數(shù)類(lèi)型為? ?的函數(shù)對(duì)其進(jìn)行重載:const?string&const?char*

    class MyClass {
    public
    void Analyze const string text );
    void 分析const char * text size_t textlen );
    };

    優(yōu)點(diǎn)

    通過(guò)重載參數(shù)不同的同名函數(shù),可以令代碼更直觀。模板化代碼需要重載,這同時(shí)也能為使用者帶來(lái)便利。

    缺點(diǎn)

    如果函數(shù)單靠不同的參數(shù)類(lèi)型而重載(acgtyrant注:這意味著參數(shù)數(shù)量不變),讀者就得十分熟悉C ++五花八門(mén)的匹配規(guī)則,以了解匹配過(guò)程具體到底如何。另外,如果派生類(lèi)只重載了某個(gè)函數(shù)的部分變體,繼承語(yǔ)義就容易令人困惑。

    結(jié)論

    如果打算重載一個(gè)函數(shù),可以試試改在函數(shù)名里加參數(shù)信息。例如,用? AppendString()和? AppendInt()?等,而不是一口氣重載多個(gè)? Append()。如果重載函數(shù)的目的是為了支持不同數(shù)量的同一類(lèi)型參數(shù),則優(yōu)先考慮使用? std::vector?以便使用者可以用? 列表初始化指定參數(shù)。

    4.5。缺省參數(shù)

    總述

    只允許在非虛函數(shù)中使用缺省參數(shù),且必須保證缺省參數(shù)的值始終一致。參數(shù)缺省與? 函數(shù)重載 ?遵循同樣的規(guī)則。一般情況下建議使用函數(shù)重載,尤其是在缺省函數(shù)帶來(lái)的可讀性提升不能彌補(bǔ)下文中所提到的缺點(diǎn)的情況下。

    優(yōu)點(diǎn)

    有些函數(shù)一般情況下使用默認(rèn)參數(shù),但有時(shí)需要又使用非默認(rèn)的參數(shù)。缺省參數(shù)為這樣的情形提供了便利,使程序員不需要為了極少的例外情況編寫(xiě)大量的函數(shù)。和函數(shù)重載相比,缺省參數(shù)的語(yǔ)法更簡(jiǎn)潔明了,減少了大量的樣板代碼,也更好地區(qū)別了“必要參數(shù)”和“可選參數(shù)”。

    缺點(diǎn)

    缺省參數(shù)實(shí)際上是函數(shù)重載語(yǔ)義的另一種實(shí)現(xiàn)方式,因此所有? 不應(yīng)當(dāng)使用函數(shù)重載的理由 ?也都適用于缺省參數(shù)。

    虛函數(shù)調(diào)用的缺省參數(shù)取決于目標(biāo)對(duì)象的靜態(tài)類(lèi)型,此時(shí)無(wú)法保證給定函數(shù)的所有重載聲明的都是同樣的缺省參數(shù)。

    缺省參數(shù)是在每個(gè)調(diào)用點(diǎn)都要進(jìn)行重新求值的,這會(huì)造成生成的代碼迅速膨脹。作為讀者,一般來(lái)說(shuō)也更希望缺省的參數(shù)在聲明時(shí)就已經(jīng)被固定了,而不是在每次調(diào)用時(shí)都可能會(huì)有不同的取值。

    缺省參數(shù)會(huì)干擾函數(shù)指針,導(dǎo)致函數(shù)簽名與調(diào)用點(diǎn)的簽名不一致。而函數(shù)重載不會(huì)導(dǎo)致這樣的問(wèn)題。

    結(jié)論

    對(duì)于虛函數(shù),不允許使用缺省參數(shù),因?yàn)樵谔摵瘮?shù)中缺省參數(shù)不一定能正常工作。如果在每個(gè)調(diào)用點(diǎn)缺省參數(shù)的值都有可能不同,在這種情況下缺省函數(shù)也不允許使用。(例如,不要寫(xiě)像? ?這樣的代碼。)void?f(int?n?=?counter++);

    在其他情況下,如果缺省參數(shù)對(duì)可讀性的提升遠(yuǎn)遠(yuǎn)超過(guò)了以上提及的缺點(diǎn)的話,可以使用缺省參數(shù)。如果仍有疑惑,就使用函數(shù)重載。

    4.6。函數(shù)返回類(lèi)型后置語(yǔ)法

    總述

    只有在常規(guī)寫(xiě)法(返回類(lèi)型前置)不便于書(shū)寫(xiě)或不便于閱讀時(shí)使用返回類(lèi)型后置語(yǔ)法。

    定義

    C ++現(xiàn)在允許兩種不同的函數(shù)聲明方式。以往的寫(xiě)法是將返回類(lèi)型置于函數(shù)名之前。例如:

    int foo int x );

    C ++ 11引入了這一新的形式。現(xiàn)在可以在函數(shù)名前使用? auto?關(guān)鍵字,在參數(shù)列表之后后置返回類(lèi)型。例如:

    auto foo int x - > int ;

    后置返回類(lèi)型為函數(shù)作用域。對(duì)于像? int?這樣簡(jiǎn)單的類(lèi)型,兩種寫(xiě)法沒(méi)有區(qū)別。但對(duì)于復(fù)雜的情況,例如類(lèi)域中的類(lèi)型聲明或者以函數(shù)參數(shù)的形式書(shū)寫(xiě)的類(lèi)型,寫(xiě)法的不同會(huì)造成區(qū)別。

    優(yōu)點(diǎn)

    后置返回類(lèi)型是顯式地指定? Lambda表達(dá)式 ?的返回值的唯一方式。某些情況下,編譯器可以自動(dòng)推導(dǎo)出Lambda表達(dá)式的返回類(lèi)型,但并不是在所有的情況下都能實(shí)現(xiàn)。即使編譯器能夠自動(dòng)推導(dǎo),顯式地指定返回類(lèi)型也能讓讀者更明了。

    有時(shí)在已經(jīng)出現(xiàn)了的函數(shù)參數(shù)列表之后指定返回類(lèi)型,能夠讓書(shū)寫(xiě)更簡(jiǎn)單,也更易讀,尤其是在返回類(lèi)型依賴于模板參數(shù)時(shí)。例如:

    template < class T class U > auto add T t U u - > decltype t + u );

    對(duì)比下面的例子:

    template < class T class U > decltype declval < T &> () + declval < U &gt ;) add T t U u );

    缺點(diǎn)

    后置返回類(lèi)型相對(duì)來(lái)說(shuō)是非常新的語(yǔ)法,而且在C和Java中都沒(méi)有相似的寫(xiě)法,因此可能對(duì)讀者來(lái)說(shuō)比較陌生。

    在已有的代碼中有大量的函數(shù)聲明,你不可能把它們都用新的語(yǔ)法重寫(xiě)一遍。因此實(shí)際的做法只能是使用舊的語(yǔ)法或者新舊混用。在這種情況下,只使用一種版本是相對(duì)來(lái)說(shuō)更規(guī)整的形式。

    結(jié)論

    在大部分情況下,應(yīng)當(dāng)繼續(xù)使用以往的函數(shù)聲明寫(xiě)法,即將返回類(lèi)型置于函數(shù)名前。只有在必要的時(shí)候(如Lambda表達(dá)式)或者使用后置語(yǔ)法能夠簡(jiǎn)化書(shū)寫(xiě)并且提高易讀性的時(shí)候才使用新的返回類(lèi)型后置語(yǔ)法。但是后一種情況一般來(lái)說(shuō)是很少見(jiàn)的,大部分時(shí)候都出現(xiàn)在相當(dāng)復(fù)雜的模板代碼中,而多數(shù)情況下不鼓勵(lì)寫(xiě)這樣? 復(fù)雜的模板代碼。

    7.命名約定

    最重要的一致性規(guī)則是命名管理。命名的風(fēng)格能讓我們?cè)诓恍枰ゲ檎翌?lèi)型聲明的條件下快速地了解某個(gè)名字代表的含義:類(lèi)型,變量,函數(shù),常量,宏,等等,甚至。我們大腦中的模式匹配引擎非常依賴這些命名規(guī)則。

    命名規(guī)則具有一定隨意性,但相比按個(gè)人喜好命名,一致性更重要,所以無(wú)論你認(rèn)為它們是否重要,規(guī)則總歸是規(guī)則。

    7.1。通用命名規(guī)則

    總述

    函數(shù)命名,變量命名,文件命名要有描述性; 少用縮寫(xiě)。

    說(shuō)明

    盡可能使用描述性的命名,別心疼空間,畢竟相比之下讓代碼易于新讀者理解更重要。不要用只有項(xiàng)目開(kāi)發(fā)者能理解的縮寫(xiě),也不要通過(guò)砍掉幾個(gè)字母來(lái)縮寫(xiě)單詞。

    int price_count_reader ; //無(wú)縮寫(xiě)
    int num_errors ; //“num”是一個(gè)常見(jiàn)的寫(xiě)法
    int num_dns_connections ; //人人都知道“DNS”是什么
    int n ; //毫無(wú)意義。
    int nerr ; //含糊不清的縮寫(xiě)。
    int n_comp_conns ; //含糊不清的縮寫(xiě)。
    int wgc_connections ; //只有貴團(tuán)隊(duì)知道是什么意思
    int pc_reader ; //“pc”有太多可能的解釋了。
    int cstmr_id ; //刪減了若干字母。

    注意,一些特定的廣為人知的縮寫(xiě)是允許的,例如用? i?表示迭代變量和用? T?表示模板參數(shù)。

    模板參數(shù)的命名應(yīng)當(dāng)遵循對(duì)應(yīng)的分類(lèi):類(lèi)型模板參數(shù)應(yīng)當(dāng)遵循? 類(lèi)型命名 ?的規(guī)則,而非類(lèi)型模板應(yīng)當(dāng)? 遵循變量命名 ?的規(guī)則。

    7.2。文件命名

    總述

    文件名要全部小寫(xiě),可以包含下劃線()或連-字符(),依照項(xiàng)目的約定。如果沒(méi)有約定,那么“ ” 更好。

    說(shuō)明

    可接受的文件命名示例:

    • my_useful_class.cc
    • my-useful-class.cc
    • myusefulclass.cc
    • myusefulclass_test.cc?//? _unittest?狀語(yǔ)從句:? _regtest?已棄用。

    C ++文件要以? .cc?結(jié)尾,頭文件以? .h?結(jié)尾。專(zhuān)門(mén)插入文本的文件則以? .inc?結(jié)尾,參見(jiàn)? 頭文件自足。

    不要使用已經(jīng)存在于? /usr/include?下的文件名(Yang.Y注:即編譯器搜索系統(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

    聯(lián)內(nèi)必須函數(shù)放在? .h?文件中。如果內(nèi)聯(lián)函數(shù)比較短,就直接放在? .h?中。

    7.3。類(lèi)型命名

    總述

    類(lèi)型名稱的每個(gè)單詞首字母均大寫(xiě),不包含下劃線:? MyExcitingClass,? MyExcitingEnum

    說(shuō)明

    所有類(lèi)型命名 - 類(lèi),結(jié)構(gòu)體,類(lèi)型定義(typedef),枚舉,類(lèi)型模板參數(shù) - 均使用相同約定,即以大寫(xiě)字母開(kāi)始,每個(gè)單詞首字母均大寫(xiě),不包含下劃線。例如:

    //類(lèi)和結(jié)構(gòu)體
    類(lèi) UrlTable {
    class UrlTableTester {
    struct UrlTableProperties {

    //類(lèi)型定義
    typedef hash_map < UrlTableProperties * string > PropertiesMap ;

    //使用別名
    使用 PropertiesMap = hash_map < UrlTableProperties * string > ;

    //枚舉
    enum UrlTableErrors {

    7.4。變量命名

    總述

    變量(包括函數(shù)參數(shù))和數(shù)據(jù)成員名一律小寫(xiě),單詞之間用下劃線連接。類(lèi)的成員變量以下劃線結(jié)尾,但結(jié)構(gòu)體的就不用,如:? a_local_variable,? a_struct_data_member,? a_class_data_member_

    說(shuō)明

    普通變量命名

    舉例:

    字符串 table_name ; //好 - 用下劃線。
    字符串 表名; //好 - 全小寫(xiě)。

    字符串 tableName ; //差 - 混合大小寫(xiě)

    類(lèi)數(shù)據(jù)成員

    不管是靜態(tài)的還是非靜態(tài)的,類(lèi)數(shù)據(jù)成員都可以和普通變量一樣,但要接下劃線。

    類(lèi) TableInfo {

    private
    string table_name_ ; //好 - 后加下劃線。
    字符串 tablename_ ; //好。
    靜態(tài) < TableInfo > * pool_ ; //好。
    };

    結(jié)構(gòu)體變量

    不管是靜態(tài)的還是非靜態(tài)的,結(jié)構(gòu)體數(shù)據(jù)成員都可以和普通變量一樣,不用像類(lèi)那樣接下劃線:

    struct UrlTableProperties {
    string name ;
    int num_entries ;
    靜態(tài) < UrlTableProperties > * ;
    };

    結(jié)構(gòu)體與類(lèi)的使用討論,參考? 結(jié)構(gòu)體與類(lèi)。

    7.5。常量命名

    總述

    聲明為? constexpr?或? const?的變量,或在程序運(yùn)行期間其值始始保持不變的,命名時(shí)以“k”開(kāi)頭,大小寫(xiě)混合。例如:

    const int kDaysInAWeek = 7 ;

    說(shuō)明

    所有具有靜態(tài)存儲(chǔ)類(lèi)型的變量(例如靜態(tài)變量或全局變量,參見(jiàn)? 存儲(chǔ)類(lèi)型)都應(yīng)當(dāng)以此方式命名。對(duì)于其他存儲(chǔ)類(lèi)型的變量,如自動(dòng)變量等,這條規(guī)則是可選的。如果不采用這條規(guī)則,就按照一般的變量命名規(guī)則。

    7.7。函數(shù)命名

    總述

    常規(guī)函數(shù)使用大小寫(xiě)混合,取值和設(shè)值函數(shù)則要求與變量名匹配:? MyExcitingFunction(),? MyExcitingMethod(),? my_exciting_member_variable(),? set_my_exciting_member_variable()

    說(shuō)明

    一般來(lái)說(shuō),函數(shù)名的每個(gè)單詞首字母大寫(xiě)(即“駝峰變量名”或“帕斯卡變量名”),沒(méi)有下劃線。對(duì)于首字母縮寫(xiě)的單詞,更傾向于將它們視作一個(gè)單詞進(jìn)行首字母大寫(xiě)(例如,寫(xiě)作? StartRpc()?而非? StartRPC())。

    AddTableEntry ()
    DeleteUrl ()
    OpenFileOrDie ()

    (同樣的命名規(guī)則同時(shí)適用于類(lèi)作用域和命名空間作用域的常量,因?yàn)樗鼈兪亲鳛锳PI的一部分暴露對(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)制要求。例如? ?與? 。int?count()void?set_count(int?count)

    7.7。命名空間命名

    總述

    命名空間以小寫(xiě)字母命名。最高級(jí)命名空間的名字取決于項(xiàng)目名稱。要注意避免嵌套命名空間的名字之間和常見(jiàn)的頂級(jí)命名空間的名字之間發(fā)生沖突。

    頂級(jí)命名空間的名稱應(yīng)當(dāng)是項(xiàng)目名或者是該命名空間中的代碼所屬的團(tuán)隊(duì)的名字。命名空間中的代碼,應(yīng)當(dāng)存放于和命名空間的名字匹配的文件夾或其子文件夾中。

    注意? 不使用縮寫(xiě)作為名稱 ?的規(guī)則同樣適用于命名空間。命名空間中的代碼極少需要涉及命名空間的名稱,因此沒(méi)有必要在命名空間中使用縮寫(xiě)。

    要避免嵌套的命名空間與常見(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)狀語(yǔ)從句:? 常量 ?或? 宏 ?harmony和諧:? kEnumName?或是? ENUM_NAME

    說(shuō)明

    的單獨(dú)枚舉值應(yīng)該優(yōu)先采用? 常量 ?的命名方式。但? 宏 ?方式的命名也。可以接受。枚舉名? UrlTableErrors?(以及? AlternateUrlTableErrors)是類(lèi)型,所以要用大小寫(xiě)混合的方式。

    enum UrlTableErrors {
    kOK = 0
    kErrorOutOfMemory
    kErrorMalformedInput
    };
    枚舉 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)該 ?使用宏。如果不得不使用,其命名像枚舉命名一樣全部大寫(xiě),使用下劃線:

    #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

    8.注意

    注釋雖然寫(xiě)起來(lái)很痛苦,但對(duì)保證代碼可讀性至關(guān)重要。下面的規(guī)則描述了如何注釋以及在哪兒注釋。當(dāng)然也要記住:注釋固然很重要,但最好的代碼應(yīng)當(dāng)本身就是文檔。有意義的類(lèi)型名和變量名,要遠(yuǎn)勝過(guò)要用注釋解釋的含糊不清的名字。

    你寫(xiě)的注釋是給代碼讀者看的,也就是下一個(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è)概念,則文件注釋?xiě)?yīng)當(dāng)對(duì)文件的內(nèi)容做一個(gè)大致的說(shuō)明,同時(shí)說(shuō)明各個(gè)概念之間的聯(lián)系。一個(gè)一到兩行的文件注釋就足夠了,對(duì)于每個(gè)概念的詳細(xì)文檔應(yīng)當(dāng)放在各個(gè)概念中,而不是文件注釋中。

    不要在? .h?和? .cc?之間復(fù)制注釋,這樣的注釋偏離了注釋的實(shí)際意義。

    8.3。類(lèi)注釋

    總述

    每個(gè)類(lèi)的定義都要附帶一份注釋,描述類(lèi)的功能和用法,除非它的功能相當(dāng)明顯。

    //遍歷GargantuanTable的內(nèi)容。
    //示例:
    // GargantuanTableIterator * iter = table-> NewIterator();
    // it for(iter-> Seek(“foo”);!iter-> done(); iter-> Next()){
    // process(iter-> key(),iter-> value());
    //}
    //刪除它;
    類(lèi) GargantuanTableIterator {

    };

    說(shuō)明

    類(lèi)注釋?xiě)?yīng)當(dāng)為讀者理解如何使用與何時(shí)使用類(lèi)提供足夠的信息,同時(shí)應(yīng)當(dāng)提醒讀者在正確使用此類(lèi)時(shí)應(yīng)當(dāng)考慮的因素。如果類(lèi)有任何同步前提,請(qǐng)用文檔說(shuō)明。如果該類(lèi)的實(shí)例可被多線程訪問(wèn),要特別注意文檔說(shuō)明多線程環(huán)境下相關(guān)的規(guī)則和常量使用。

    如果你想用一小段代碼演示這個(gè)類(lèi)的基本用法或通常用法,放在類(lèi)注釋里也非常合適。

    如果類(lèi)的聲明和定義分開(kāi)了(例如分別放在了? .h?和? .cc?文件中),此時(shí),描述類(lèi)用法的注釋?xiě)?yīng)當(dāng)和接口定義放在一起,描述類(lèi)的操作和實(shí)現(xiàn)的注釋?xiě)?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ù))。注釋使用敘述式(“打開(kāi)文件”)而非指令式(“打開(kāi)文件”); 注釋只是為了描述函數(shù),而不是命令函數(shù)做什么。通常,注釋不會(huì)描述函數(shù)如何工作。那是函數(shù)定義部分的事情。

    函數(shù)聲明處注釋的內(nèi)容:

    • 函數(shù)的輸入輸出。
    • 對(duì)類(lèi)成員函數(shù)而言:函數(shù)調(diào)用期間對(duì)象是否需要保持引用參數(shù),是否會(huì)釋放這些參數(shù)。
    • 函數(shù)是否分配了必須由調(diào)用者釋放的空間。
    • 參數(shù)是否可以為空指針。
    • 是否存在函數(shù)使用上的性能隱患。
    • 如果函數(shù)是可重入的,其同步提提是什么?

    舉例如下:

    //返回此表的迭代器。
    當(dāng)?shù)魍瓿蓵r(shí),它是
    客戶端的責(zé)任//并且一旦
    創(chuàng)建
    迭代器的GargantuanTable對(duì)象被刪除,它就不能使用迭代器//
    //迭代器最初位于表的開(kāi)始位置。
    //
    //此方法等同于:
    // Iterator * iter = table-> NewIterator();
    // iter-> Seek(“”);
    //返回iter;
    //如果您要立即尋找到
    返回的迭代器
    中的其他位置,則使用NewIterator()會(huì)更快,并避免額外的查找。
    Iterator * GetIterator () const;

    但也要避免羅羅嗦嗦,或者對(duì)顯著易見(jiàn)的內(nèi)容進(jìn)行說(shuō)明。下面的注釋就沒(méi)有必要加上“否則返回false”,因?yàn)橐呀?jīng)暗含其中了:

    //如果表不能包含更多條目,則返回true。
    bool IsTableFull ();

    注釋函數(shù)重載時(shí),注釋的重點(diǎn)應(yīng)該是函數(shù)中被重載的部分,而不是簡(jiǎn)單的重復(fù)被重載的函數(shù)的注釋。多數(shù)情況下,函數(shù)重載不需要額外的文檔,因此也沒(méi)有必要加上注釋。

    注釋構(gòu)造/析構(gòu)函數(shù),切記讀代碼的人知道構(gòu)造/析構(gòu)函數(shù)的所有功能,所以“銷(xiāo)毀這一對(duì)象”這樣的注釋是沒(méi)有意義的。你應(yī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ō)明

    類(lèi)數(shù)據(jù)成員

    每個(gè)類(lèi)數(shù)據(jù)成員(也叫實(shí)例變量或成員變量)都應(yīng)該用注釋說(shuō)明用途。如果有非變量的參數(shù)(例如特殊值,數(shù)據(jù)成員之間的關(guān)系,生命周期等)不能夠使用類(lèi)型與變量名明確表達(dá),則應(yīng)當(dāng)加上注釋。然而,如果變量類(lèi)型與變量名已經(jīng)足夠描述一個(gè)變量,那么就不需要加上注釋。

    特別地,如果變量可以接受? NULL?或? -1?等警戒值,須加以說(shuō)明。比如:

    private
    //用于限制檢查表訪問(wèn)。-1意味著
    //我們還不知道表中有多少個(gè)條目。
    int num_total_entries_ ;

    全局變量

    和數(shù)據(jù)成員一樣,所有全局變量也要注釋說(shuō)明含義及用途,以及作為全局變量的原因。比如:

    //在此回歸測(cè)試中我們經(jīng)歷的測(cè)試用例的總數(shù)。
    const int kNumTestCases = 6 ;

    8.6。實(shí)現(xiàn)注釋

    總述

    對(duì)于代碼中巧妙的,晦澀的,有趣的,重要的地方加以注釋。

    說(shuō)明

    代碼前注釋

    巧妙或復(fù)雜的代碼段前要加注釋。比如:

    //將結(jié)果除以2,考慮到x
    //包含來(lái)自add的進(jìn)位。
    for int i = 0 ; i < result - > size (); i ++ {
    x = x << 8 + * result )[ i ];
    * 結(jié)果)[ i ] = x >> 1 ;
    x &= 1 ;
    }

    行注釋

    比較隱晦的地方要在行尾加入注釋。在行尾空兩格進(jìn)行注釋。比如:

    //如果我們有足夠的內(nèi)存,也可以對(duì)數(shù)據(jù)部分進(jìn)行mmap。
    mmap_budget = max < int64 > 0 mmap_budget - index_ - > length ());
    if mmap_budget > = data_size_ && MmapData mmap_chunk_bytes mlock ))
    return ; //錯(cuò)誤已經(jīng)記錄。

    注意,這里用了兩段注釋分別描述這段代碼的作用,并提示函數(shù)返回錯(cuò)誤已經(jīng)被記入日志。

    如果你需要連續(xù)進(jìn)行多行注釋,可以使之對(duì)齊獲得更好的可讀性:

    DoSomething (); //在這里發(fā)表評(píng)論,以便評(píng)論排成一行。
    DoSomethingElseThatIsLonger (); //代碼和注釋之間有兩個(gè)空格。
    { //允許打開(kāi)一個(gè)新的作用域時(shí),在注釋之前的一個(gè)空格
    // //因此注釋與下面的注釋和代碼一起排列。
    DoSomethingElse (); //通常在行注釋之前有兩個(gè)空格。
    }
    std :: vector < string > list {
    //支撐列表中的注釋描述下一個(gè)元素…
    “First item”
    // …并且應(yīng)該適當(dāng)?shù)貙?duì)齊。
    “第二項(xiàng)” };
    做一點(diǎn)事(); / 對(duì)于尾部塊注釋,一個(gè)空間可以。 /

    函數(shù)參數(shù)注釋

    如果函數(shù)參數(shù)的意義不明顯,考慮用下面的方式進(jìn)行彌補(bǔ):

    • 如果參數(shù)是一個(gè)字面常量,并且這一常量在多處函數(shù)調(diào)用中被使用,用以推斷它們一致,你應(yīng)該用一個(gè)常量名讓這個(gè)約定變得更明顯,并且保證這一約定不會(huì)被打破。
    • 考慮更改函數(shù)的簽名,讓某個(gè)? bool?類(lèi)型的參數(shù)變?yōu)? enum?類(lèi)型,這樣可以讓這個(gè)參數(shù)的值表達(dá)其意義。
    • 如果某個(gè)函數(shù)有多個(gè)配置選項(xiàng),你可以考慮定義一個(gè)類(lèi)或結(jié)構(gòu)體以保存所有的選項(xiàng),并傳入類(lèi)或結(jié)構(gòu)體的實(shí)例。這樣的方法有許多優(yōu)點(diǎn),例如這樣的選項(xiàng)可以在調(diào)用處用變量名引用,這樣就能清晰地表明其意義。同時(shí)也減少了函數(shù)參數(shù)的數(shù)量,使得函數(shù)調(diào)用更易讀也易寫(xiě)。除此之外,以這樣的方式,如果你使用其他的選項(xiàng),就無(wú)需對(duì)調(diào)用點(diǎn)進(jìn)行更改。
    • 用具名變量代替大段而復(fù)雜的嵌套表達(dá)式。
    • 萬(wàn)不得已時(shí),才考慮在調(diào)用點(diǎn)用注釋闡明參數(shù)的意義。

    比如下面的示例的對(duì)比:

    //這些論據(jù)是什么?
    const DecimalNumber product = CalculateProduct values 7 false nullptr );

    ProductOptions 選項(xiàng);
    選項(xiàng)set_precision_decimals 7 );
    選項(xiàng)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 ++水平比你高,即便他/她可能不知道你的用意:

    你所提供的注釋?xiě)?yīng)當(dāng)解釋代碼? 為什么 ?要這么做和代碼的目的,或者最好是讓代碼自文檔化。

    比較這樣的注釋:

    //在矢量中查找元素。< - 差:這太明顯了!
    自動(dòng) ITER = STD :: 找到v 開(kāi)始(), v (), 元素);
    如果 ITER =! v ()) {
    過(guò)程元件);
    }

    和這樣的注釋:

    //處理“元素”,除非它已經(jīng)被處理。
    自動(dòng) ITER = STD :: 找到v 開(kāi)始(), v (), 元素);
    如果 ITER =! v ()) {
    過(guò)程元件);
    }

    自文檔化的代碼根本就不需要注釋。上面例子中的注釋對(duì)下面的代碼來(lái)說(shuō)就是毫無(wú)必要的:

    if IsAlreadyProcessed element )) {
    Process element );
    }

    8.8。標(biāo)點(diǎn),拼寫(xiě)和語(yǔ)法

    總述

    注意標(biāo)點(diǎn),拼寫(xiě)和語(yǔ)法; 寫(xiě)的好的注釋比差的要易讀的多。

    說(shuō)明

    注釋的通常寫(xiě)法是包含正確大小寫(xiě)和結(jié)尾句號(hào)的完整敘述性語(yǔ)句。大多數(shù)情況下,完整的句子比句子片段可讀性更高。短一點(diǎn)的注釋,比如代碼行尾注釋,可以隨意點(diǎn),但依然要注意風(fēng)格的一致性。

    雖然被別人指出該用分號(hào)時(shí)卻用了逗號(hào)多少有些尷尬,但清晰易讀的代碼還是很重要的。正確的標(biāo)點(diǎn),拼寫(xiě)和語(yǔ)法對(duì)此會(huì)有很大幫助。

    8.8。TODO注釋

    總述

    對(duì)那些臨時(shí)的,短期的解決方案,或已經(jīng)夠好,但仍不完美的代碼使用? TODO?注釋。

    TODO?注意要使用全大寫(xiě)的字符串? TODO,在隨后的圓括號(hào)里寫(xiě)上你的名字,郵件地址,bug ID,或其它身份標(biāo)識(shí)和與這一? TODO?相關(guān)的問(wèn)題。主要目的是讓添加注釋的人(也是可以請(qǐng)求提供更多細(xì)節(jié)的人)可根據(jù)規(guī)范的? TODO?格式進(jìn)行查找。添加? TODO?注釋并不意味著你要自己來(lái)修正,因此當(dāng)你加上帶有姓名的時(shí)候? TODO?,一般都是寫(xiě)上自己的名字。

    // TODO(kl@gmail.com):這里使用“*”作為連接運(yùn)算符。
    // TODO(Zeke)將其改為使用關(guān)系。
    // TODO(錯(cuò)誤12345):刪除“最后訪問(wèn)者”功能

    如果加? TODO?是為了在“將來(lái)某一天做某事”,可以附上一個(gè)非常明確的時(shí)間“Fix by November 2005”),或者一個(gè)明確的事項(xiàng)(“所有客戶端都可以處理XML響應(yīng)時(shí)刪除此代碼。”) 。

    8.9。棄用注釋

    總述

    通過(guò)棄用注釋(DEPRECATED?評(píng)論)以標(biāo)記某接口點(diǎn)已棄用。

    您可以寫(xiě)上包含全大寫(xiě)的? DEPRECATED?注釋,以標(biāo)記某接口為棄用狀態(tài)。注釋可以放在接口聲明前,或者同一行。

    DEPRECATED?一詞后,在? 括號(hào)中留下您的名字,郵箱地址以及其他身份標(biāo)識(shí)。

    棄用注釋?xiě)?yīng)當(dāng)包涵簡(jiǎn)短而清晰的指引,以幫助其他人修復(fù)其調(diào)用點(diǎn)。在C ++中,你可以將一個(gè)棄用函數(shù)改造成一個(gè)內(nèi)聯(lián)函數(shù),這一函數(shù)將調(diào)用新的接口。

    DEPRECATED?僅僅標(biāo)記接口為并? 不允許大家不約而同地棄用,您還得親自主動(dòng)修正調(diào)用點(diǎn)(callsites),或是找個(gè)幫手。

    修正好的代碼應(yīng)該不會(huì)再涉及棄用接口點(diǎn)了,著實(shí)改用新接口點(diǎn)。如果您不知從何下手,可以找標(biāo)記棄用注釋的當(dāng)事人一起商量。

    9.格式

    每個(gè)人都可能有自己的代碼風(fēng)格和格式,但如果一個(gè)項(xiàng)目中的所有人都遵循同一風(fēng)格的話,這個(gè)項(xiàng)目就能更順利地進(jìn)行。每個(gè)人未必能同意下述的每一處格式規(guī)則,而且其中的不少規(guī)則需要一定時(shí)間的適應(yīng),但整個(gè)項(xiàng)目服從統(tǒng)一的編程風(fēng)格是很重要的,只有這樣才能讓所有人輕松地閱讀和理解代碼。

    為了幫助你正確的格式化代碼,我們寫(xiě)了一個(gè)? emacs配置文件。

    9.1。行長(zhǎng)度

    總述

    每一行代碼字符數(shù)不超過(guò)80。

    我們也認(rèn)識(shí)到這條規(guī)則是有爭(zhēng)議的,但很多已有代碼都遵照這一規(guī)則,因此我們感覺(jué)一致性更重要。

    優(yōu)點(diǎn)

    提倡該原則的人認(rèn)為強(qiáng)迫他們調(diào)整編輯器窗口大小是很野蠻的行為。很多人同時(shí)并排開(kāi)幾個(gè)代碼窗口,根本沒(méi)有多余的空間拉伸窗口。大家都把窗口最大尺寸加以限定,并且80列寬是傳統(tǒng)標(biāo)準(zhǔn)。那么為什么要改變呢?

    缺點(diǎn)

    反對(duì)該原則的人則認(rèn)為更寬的代碼行更易閱讀。80列的限制是上個(gè)世紀(jì)60年代的大型機(jī)的古板缺陷; 現(xiàn)代設(shè)備具有更寬的顯示屏,可以很輕松地顯示更多代碼。

    結(jié)論

    80個(gè)字符是最大值。

    如果無(wú)法在不傷害易讀性的條件下進(jìn)行斷行,那么注釋行可以超過(guò)80個(gè)字符,這樣可以方便復(fù)制粘貼。例如,帶有命令示例或URL的行可以超過(guò)80個(gè)字符。

    長(zhǎng)所有游戲的路徑? #include?語(yǔ)句可以超出80列。

    文件頭保護(hù) ?可以無(wú)視該原則。

    9.2。非ASCII字符

    總述

    盡量不使用非ASCII字符,使用時(shí)必須使用UTF-8編碼。

    說(shuō)明

    即使是英文,也不應(yīng)將用戶界面的文本硬編碼到源代碼中,因此非ASCII字符應(yīng)當(dāng)很少被用到。特殊情況下可以適當(dāng)包含此類(lèi)字符。例如,代碼分析外部數(shù)據(jù)文件時(shí),可以適當(dāng)硬編碼數(shù)據(jù)文件中作為分隔符的非ASCII字符串; 更常見(jiàn)的是(不需要本地化的)單元測(cè)試代碼可能包含非ASCII字符串。此類(lèi)情況下,應(yīng)使用UTF-8編碼,因?yàn)楹芏喙ぞ叨伎梢岳斫夂吞幚鞺TF-8編碼。

    十六進(jìn)制編碼也可以,能增強(qiáng)可讀性的情況下尤其鼓鼓 - 比如? “\xEF\xBB\xBF”,或者更簡(jiǎn)潔地寫(xiě)作? u8"\uFEFF",在Unicode中是? 零寬度無(wú)間斷 ?的間隔符號(hào),如果不用十六進(jìn)制直接放在UTF -8格式的源文件中,是看不到的。

    (Yang.Y注:? “\xEF\xBB\xBF”?通常用作帶編碼標(biāo)記的UTF-8)

    使用? u8?前綴把帶? uXXXX?轉(zhuǎn)義序列的字符串字面值編碼成UTF-8。不要用在本身就帶UTF-8字符的字符串字面值上,因?yàn)槿绻幾g器不把源代碼識(shí)別成UTF-8,輸出就會(huì)出錯(cuò)。

    別用C ++ 11的? char16_t?和? char32_t,它們和UTF-8文本沒(méi)有關(guān)系,? wchar_t?同理,除非你寫(xiě)的代碼要調(diào)用Windows API,后者廣泛使用了? wchar_t

    9.3。空格還是制表位

    總述

    <span style="font-family:‘Microsoft YaHei’

    總結(jié)

    以上是生活随笔為你收集整理的【代码规范】google开源c\c++项目代码规范的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。