0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

Google的C++代碼規(guī)范是全球最好的一份C++代碼規(guī)范

C語言專家集中營 ? 來源:未知 ? 作者:李倩 ? 2018-09-27 17:54 ? 次閱讀

李開復曾在微博上說過,Google的C++代碼規(guī)范是全球最好的一份C++代碼規(guī)范,沒有之一。最近花了點時間看了下這份代碼規(guī)范,收獲確實很大,在編程過程中一些亂七八糟的壞習慣也該改一改了。

下面幾個是我個人覺得收獲比較大的幾點,要看完整版的,可以自己下載。

頭文件

函數參數順序

C/C++函數參數分為輸入參數和輸出參數兩種,有時輸入參數也會輸出(注:值被修改時)。輸入參數一般傳值或常數引用(const references),輸出參數戒輸入/輸出參數為非常數指針(non-const pointers)。對參數排序時,將所有輸入參數置于輸出參數之前。不要僅僅因為是新添加的參數,就將其置于最后,而應該依然置于輸出參數之前。這一點并不是必須遵循的規(guī)則,輸入/輸出兩用參數(通常是類/結構體變量)混在其中,會使得規(guī)則難以遵守。

個人感受:這條規(guī)則相當重要,自己寫代碼的時候可能沒有太大感覺,但是在閱讀別人代碼的時候感覺特別明顯。如果代碼按照這種規(guī)范來寫,從某種角度來說,這段代碼具有“自注釋”的功能,那么在看代碼的時候就會比較輕松。Doom3的代碼規(guī)范中提到,“Use ‘const’ as much as possible”,也是同樣的意義。當然,const除了閱讀方便以外,還有個很重要的就是防止編碼錯誤,一旦在程序中修改const變量,編譯器就會報錯,這樣就減少了人工出錯了可能性,這點尤為重要!

包含文件的名稱及次序

將包含次序標準化可增強可讀性、避免隱藏依賴(hidden dependencies,注:隱藏依賴主要是指包含的文件編譯),次序如下:C 庫、C++庫、其他庫的.h、項目內的.h。

項目內頭文件應挄照項目源代碼目錄樹結構排列,并且避免使用UNIX文件路徑.(當前目錄)和..(父目錄)。

舉例來說,google-awesome-project/src/foo/internal/fooserver.cc 的包含次序如下:#include "foo/public/fooserver.h" // 優(yōu)先位置#include #include #include #include #include "base/basictypes.h"#include "base/commandlineflags.h"#include "foo/public/bar.h"

注意,對應的頭文件一定要先包含,這樣避免隱藏依賴,隱藏依賴的問題不懂的可以去Google,網上有很多資料。另外,《C++編程思想》中提到的包含次序正好相反,從特殊到一般,但是有一點和Google代碼規(guī)范是一樣的,那就是對應的頭文件是第一個包含。對于隱藏依賴的問題,以前只是習慣性的把對應的頭文件放第一個,沒有想過為什么,現在學習了……

作用域

全局變量

class 類型的全局變量是被禁止的,內建類型的全局變量是允許的,當然多線程代碼中非常數全局變量也是被禁止的。永遠不要使用函數返回值初始化全局變量。

不幸的是,全局變量的構造函數、析構函數以及初始化操作的調用順序只是被部分規(guī)定,每次生成有可能會有變化,從而導致難以發(fā)現bug。因此,禁止使用class類型的全局變量(包括STL的string,vector等),因為它們的初始化順序可能會導致出現問題。內建類型和由內建類型構成的沒有構造函數的結構體可以使用,如果你一定要使用class類型的全局變量,請使用單件模式。

C++類

構造函數的職責

構造函數中只進行那些沒有實際意義的初始化,可能的話,使用Init()方法集中初始化為有意義(non-trivial)的數據。

個人感受:這種做法可以從一開始就避免一些bug的出現,或更容易解決一些bug。構造函數+Init()函數初始化的方式與只用構造函數的方法相比,對計算機來說他們是沒有區(qū)別的,但是人是會犯錯的,這一條代碼規(guī)范在某種程度上避免了一些人為錯誤,這個在開發(fā)中特別重要。

拷貝構造函數

僅在代碼中需要拷貝一個類的對象的時候使用拷貝構造函數,不需要拷貝時使用DISALLOW_COPY_AND_ASSIGN這個宏(關于這個宏的內容,可以在網上搜到,我這里就不寫了)。C++中對象的隱式拷貝是導致很多性能問題和bugs的根源??截悩嬙旌瘮到档土舜a可讀性,相比按引用傳遞,跟蹤按值傳遞的對象更加困難,對象修改的地方變得難以捉摸。

個人感受:和上一項的目的類似,為了避免人為錯誤!拷貝構造函數本來是為了方便程序員編程了,但是卻有可能成為一個坑,為了避免這類問題,不需要拷貝時使用DISALLOW_COPY_AND_ASSIGN,這樣在需要調用拷貝構造函數的時候就會報錯,減少了人為出錯的可能性。C#Java在這方面就做得比較好,雖然性能上不如C++,但是人為出錯的概率減少了很多。當然,使用一定的代碼規(guī)范,可以在一定程度上減少C++的坑。

繼承

雖然C++的繼承很好用,但是在實際開發(fā)中,盡量多用組合少用繼承,不懂的去看GoF的《Design Patterns》。

但重定義派生的虛函數時,在派生類中明確聲明其為virtual。這一條是為了為了閱讀方便,雖然從語法的角度來說,在基類中聲明了virtual,子類可以不用再聲明該函數為virtual,但這樣一來閱讀代碼的人需要檢索類的所有祖先以確定該函數是否為虛函數o(╯□╰)o。

多重繼承

雖然允許,但是只能一個基類有實現,其他基類是接口,這樣一來和JAVA一樣了。這些東西在C#和JAVA中都進行了改進,直接從語法上解決問題。C++的靈活性過高,也是個麻煩的問題,只能通過代碼規(guī)范填坑。

接口

虛基類必須以Interface為后綴,方便閱讀。閱讀方便。

重載操作符

除少數特定情況外,不要重載操作符?。。 ?=”和“=”的操作Euqals和CopyFrom函數代替,這樣更直觀,也不容易出錯。

個人感受:看到這一條,我有點驚訝,在學習C++的時候,說重載操作符有神馬神馬好處,為什么現在又說不要重載操作符呢?仔細看了他的文檔,確實說的有道理,導致可能出現的bug見其具體文檔。在實際應用中,由于C++的坑實在太多了,不得不把這種“好用”的東西干掉,因為出了bug又找不到,是一件很O疼的事情。

聲明次序

1)typedefs和enums;

2)常量;

3)構造函數;

4)析構函數;

5)成員函數,含靜態(tài)成員函數;

6)數據成員,含靜態(tài)數據成員。

宏 DISALLOW_COPY_AND_ASSIGN 置于private:塊之后,作為類的最后部分。

其他C++特性

引用參數

函數形參表中,所有的引用必須的const!

個人感受:這么做是為了防止引用引起的誤解,因為引用在語法上是值,卻有指針的意義。雖然引用比較好用,但是犧牲其某些方面的特性,換來軟件管理方面的便利,還是很值得了。

缺省參數

禁止使用函數缺省參數!

個人感受:看到這一點的時候覺得有點因噎廢食了,其實缺省參數感覺還是蠻好用的。當然從另外一個角度來說,要使用C++就不要怕這種小麻煩,如果因為使用這些特性造成了找不到的bug,那會損失更多時間。

異常

不要使用C++異常。

這一點我沒有看懂,也許是因為它的異常機制沒有C#和Java那么完善吧……畢竟在C#和Java里面異常還是很好用的東東。

除了記錄日志,不要使用流,使用printf之類的代替。

這一條其實是有一些爭議的,當然大多數人認為代碼一致性比較重要,所以選擇printf,具體的可以看原文文檔。

const的使用

在任何可以的情況下都要使用const。

這條規(guī)則贊一個,Doom3的代碼規(guī)范里也提到了這一條。這么做有兩個好處,一個是防止程序出錯,因為修改了const類型的變量會報錯;另一個就是方便閱讀,使代碼“自注釋”。雖然這么做也有壞處,當然,總體來說利大于弊。

命名約定

1、總體規(guī)則:不要隨意縮寫,如果說 ChangeLocalValue 寫作ChgLocVal還有情可原的話,把ModifyPlayerName寫作MdfPlyNm就太過分了,除函數名可適當為動詞外,其他命名盡量使用清晰易懂的名詞;

2、宏、枚舉等使用全部大寫+下劃線;

3、變量(含類、結構體成員變量)、文件、命名空間、存取函數等使用全部小寫+下劃線,類成員變量以下劃線結尾,全局變量以g_開頭;

4、普通函數、類型(含類與結構體、枚舉類型)、常量等使用大小寫混合,不含下劃線;

使用這套命名約定,可以使代碼具有一定程度的“自注釋”功能,方便他人閱讀,也方便自己以后修改。當然3、4兩點也可以使用其他的命名約定,只要團隊統一即可。

格式

1、行寬原則上不超過80列,把22寸的顯示屏都占完,怎么也說不過去;

2、盡量不使用非ASCII字符,如果使用的話,參考 UTF-8 格式(尤其是 UNIX/Linux 下,Windows 下可以考慮寬字符),盡量不將字符串常量耦合到代碼中,比如獨立出資源文件,返不僅僅是風格問題了;

3、UNIX/Linux下無條件使用空格,MSVC的話使用 Tab 也無可厚非; (我沒用過Linux,不懂為什么在Linux下無條件使用空格)

4、函數參數、邏輯條件、初始化列表:要么所有參數和函數名放在同一行,要么所有參數并排分行;

5、除函數定義的左大括號可以置于行首外,包括函數/類/結極體/枚舉聲明、各種語句的左大括號置于行尾,所有右大括號獨立成行;

6、./->操作符前后丌留空格,*/&不要前后都留,一個就可,靠左靠右依各人喜好;

7、預處理指令/命名空間不使用額外縮進,類/結構體/枚舉/函數/語句使用縮進;

8、初始化用=還是()依個人喜好,統一就好;

9、return不要加();

10、水平/垂直留白不要濫用,怎么易讀怎么來。

寫在最后

總的來說,這套代碼規(guī)范還是相當不錯的,既有防止錯誤使用C++的某些特性而導致bugs的規(guī)范,又有代碼書寫的相關規(guī)范使其便于閱讀,建議搞C++的童鞋都看一看。當然,具體的團隊應該會有具體的代碼規(guī)范,代碼風格方面大家可能會有一些區(qū)別;不使用C++某些特性(比如不使用C++異常,禁止使用函數缺省參數)方面,應該按照具體情況進行折中處理,而不應該生搬硬套代碼規(guī)范;但是“不將字符串常量耦合到代碼中”這種規(guī)范,是大家必須遵守的。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規(guī)問題,請聯系本站處理。 舉報投訴
  • Google
    +關注

    關注

    5

    文章

    1754

    瀏覽量

    57380
  • C++
    C++
    +關注

    關注

    21

    文章

    2102

    瀏覽量

    73453
  • 代碼
    +關注

    關注

    30

    文章

    4723

    瀏覽量

    68242

原文標題:閱讀Google的C++代碼規(guī)范有感

文章出處:【微信號:C_Expert,微信公眾號:C語言專家集中營】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    寫好C++代碼需要遵循的10個最佳實踐

    C++代碼提供了足夠的靈活性,因此對于大部分工程師來說都很難把握。本文介紹了寫好C++代碼需要遵循的10個最佳實踐,并在最后提供了個工具可
    發(fā)表于 09-19 09:30 ?696次閱讀

    Google C++編程指南

    Google C++編程指南目標:增強代碼致性,創(chuàng)建通用的、必需的習慣用語和模式可以使代碼更加容易理解
    發(fā)表于 11-29 09:15

    大家誰有串口調試助手的源碼,最好C++的能發(fā)我一份嗎,謝謝了

    大家誰有串口調試助手的源碼,最好C++的能發(fā)我一份嗎,謝謝了大家誰有串口調試助手的源碼,最好C++的能發(fā)我
    發(fā)表于 01-28 22:24

    C/ C++代碼自動測試工具規(guī)格說明

    C/ C++代碼自動測試工具規(guī)格說明1. 靜態(tài)測試1.1 內建700條以上業(yè)界公認的編碼規(guī)范,可以驗證用戶源代碼,并檢
    發(fā)表于 02-09 14:58 ?44次下載

    如何在C++代碼中使用C頭文件

    如何在C++代碼中使用C頭文件。從C++調用C頭文件之前,C頭文件必須包含在extern
    發(fā)表于 10-19 09:24 ?3次下載

    張圖總結Google C++編程規(guī)范

    Google C Style Guide是一份不錯的C編碼指南,我制作了張比較全面的說明圖,可以在短時間內快速掌握
    發(fā)表于 11-26 15:25 ?1453次閱讀

    C++容器的使用代碼資料總結免費下載

    本文檔的主要內容詳細介紹的是C++容器的使用代碼資料總結免費下載。
    發(fā)表于 01-29 10:52 ?3次下載
    <b class='flag-5'>C++</b>容器的使用<b class='flag-5'>代碼</b>資料總結免費下載

    Google C++編程風格指南PDF版免費下載

    Google的項目大多使用C++開發(fā)。每C++程序員也都知道, C++具有很多強大的語言特性,但這種強大不可避免的導致它的復雜,而復雜性
    發(fā)表于 03-06 08:00 ?0次下載
    <b class='flag-5'>Google</b> <b class='flag-5'>C++</b>編程風格指南PDF版免費下載

    C++語言編碼規(guī)范詳細說明

    本文檔的主要內容詳細介紹的是C++語言編碼規(guī)范詳細說明。
    發(fā)表于 01-07 16:19 ?14次下載
    <b class='flag-5'>C++</b>語言編碼<b class='flag-5'>規(guī)范</b>詳細說明

    手機模擬系統的C++代碼免費下載

    本文檔的主要內容詳細介紹的是手機模擬系統的C++代碼免費下載。
    發(fā)表于 09-23 08:00 ?0次下載
    手機模擬系統的<b class='flag-5'>C++</b>源<b class='flag-5'>代碼</b>免費下載

    C++ Socket網絡編程大全源代碼下載

    C++ Socket網絡編程大全源代碼下載
    發(fā)表于 06-21 09:36 ?25次下載

    qt用C++寫的2048小游戲源代碼

    qt用C++寫的2048小游戲源代碼
    發(fā)表于 09-27 11:48 ?1次下載

    C++項目常見的命名規(guī)范

    本系列是開源書C++ Best Practises[1]的中文版,全書從工具、代碼風格、安全性、可維護性、可移植性、多線程、性能、正確性等角度全面介紹了現代C++項目的最佳實踐。本文是該系列的第二篇。
    的頭像 發(fā)表于 09-27 09:12 ?2044次閱讀

    C++代碼需要遵循的10個最佳實踐

    C++代碼提供了足夠的靈活性,因此對于大部分工程師來說都很難把握。本文介紹了寫好C++代碼需要遵循的10個最佳實踐,并在最后提供了個工具可
    的頭像 發(fā)表于 10-18 15:20 ?803次閱讀

    CC++混合編程是什么

    這篇文章講解的知識點很“小”,但是在CC++的混合編程中非常重要。因為我們在寫應用程序時,經常利用到第三方的程序。如果我們的代碼C,但是第三方
    的頭像 發(fā)表于 02-14 13:48 ?1588次閱讀
    <b class='flag-5'>C</b>與<b class='flag-5'>C++</b>混合編程是什么