《C++編程規範》讀書筆記(上)

來源:互聯網
上載者:User

      項目組一直沒有做代碼審查,最近有啟動這項計劃的打算,因此提前複習一下《C++編程規範》,並做一些筆記。我們做任何事通常都先從簡單的入手,循序漸進,持續改進,那麼做代碼審查也不例外,《C++編程規範》又很多,如果一下子突然引入,會對代碼編寫提出過高的要求,對開發人員的打擊比較大,從而可能會影響團隊的整個士氣,所以我想我們應該從最簡單(即容易遵循做到)、最重要的幾個規範開始,即追求 【有效性/複雜性】 最大化。

     聯想到排程的十字表格,如法炮製了如下表格,以便分門別類:

代碼審查
B(簡單&很重要) C(複雜&很重要)
A(簡單&較重要) D(複雜&較重要)

    當然,規範本沒有重要與不重要之分,這裡這樣給其畫上這樣的標籤,只是一個相對的概念,是給我們推進“代碼審查”這項工作一個簡單的指引,例如先實施A區的規則,一段時間後,當團隊成員都習慣了這些規則,再實施B區的規則,基本上按照先易後難的順序,依次推進。

    由於筆者的學識水平,以及經驗所致,對一些規則的認識肯定存在偏差與不妥,還請同學批評賜教。

  《C++編程規範——101條規則、準則與最佳實務》(C++ Coding Standards——101 Rules, Guidelines and Best Practices)

組織和策略問題

 第0條(D): 不要拘泥於小節(又名:瞭解哪些東西不應該標準化)

      是的,有些東西不應該規定過死。但是我們認為,在一些個人風格和喜好方面,保持團隊內部的一致性是有好處的。一致性的重要性似乎怎麼強調都不過分。

第1條(B):在高警告層級下乾淨利落地進行編譯

      將編譯器的警告層級調到最高,高度重視警告。編譯器是我們的好朋友,如果它對某個構建發出警告,就說明這個構建可能存在潛在的問題。這個問題可能是良性的,也可能是惡性的。我們應該通過修改代碼而不是降低警告層級來消除警告。

第2條(C):使用自動構建系統

      “一鍵構建”,甚至使構建伺服器根據代碼的提交自動進行構建,持續整合,不斷交付軟體產品,在迭代中完善。儘管現在有了很多開源的自動化構建系統,但是搭建並維護這樣一個自動化構建系統,需要團隊中有一位經驗豐富的高手。

第3條(B):使用版本控制系統(VCS)

       VSS, SVN, GIT。

第4條(*):做代碼審查

      審查代碼:更多的關注有助於提高品質。亮出自己的代碼,閱讀別人的代碼。互相學習,彼此都會受益。代碼審查無需太形式主義,但一定要做,團隊可根據自己的實際情況嘗試著去做,在做的過程中,慢慢改進,找到一個符合團隊實際需要的方式。CppCheck

設計風格

第5條(C):一個實體應該只有一個緊湊的職責

      一次只解決一個問題:只給一個實體(變數、類、函數、名字空間、模組和庫)賦予一個定義良好的職責。隨著實體變大,其職責範圍自然也會擴大,但是職責不應該發散。

第6條(C):正確、簡單和清晰第一

      軟體簡單為美(KISS原則:Keep It Simple Software):品質優於速度;簡單優於複雜;清晰優於機巧;安全第一。可讀性:代碼必須是為人編寫的,其次才是電腦。

第7條(C):編程中應該知道何時和如何考慮延展性

    面對資料的爆炸性增長,應該集中精力改善演算法的O(N)複雜度。在這種情況下,小型的最佳化(例如節約一個賦值、加法或乘法運算)通常無濟於事。

第8條(A):不要進行不成熟的最佳化

第9條(A):不要進行不成熟的劣化

     構造既清晰又有效程式有兩種方式:使用抽象(DIP)和庫(STL)。

第10條(B):盡量減少全域和共用資料

第11條(C):隱藏資訊

第12條(D):懂得何時和如何進行並發性編程

      安全執行緒?並發編程?加鎖解鎖死結?這些對我來說還只是屬於概念......,鄙視一下自己!

第13條(B):確保資源為對象所擁有。使用顯式的RAII和智能指標

     利器在手,不要再徒手為之。當然,也要防止智能指標的過度使用。如果只對有限的代碼可見(例如函數內部,類內部),原始指標就夠用了。

編程風格

第14條(C):寧要編譯時間和串連時錯誤,也不要執行階段錯誤

第15條(A):積極的使用const

     const是我們的朋友,不變的值更易於理解,跟蹤和分析。定義值的時候,應該將const作為預設選項。用mutable成員變數實現邏輯上的不變性,在給某些資料做緩衝處理的時候經常使用這一特性。即在類的const成員函數中可以合法的修改類的mutable成員變數。

     當然,對於那種通過值傳遞的函數參數聲明為const 純屬多此一舉,反而還會引起誤解。

第16條(D):避免使用宏

     這似乎是C++中一條人人皆知的編程規範。可真正嚴格遵守的團隊並不多(純屬猜想,哈哈)。

第17條(D):避免使用“魔數”

    同第16條。

    應該用符號常量替換直接寫死的字串(或宏)。將字串與代碼分開(比如將字串放入一個獨立的CPP檔案中),這樣有利於審查和更新,而且有助於國家化。

第18條(A):儘可能局部地聲明變數

    避免範圍膨脹。變數的生存期越短越好。因此,儘可能只在首次使用變數之前聲明之(通常這時你也有足夠的資料對它初始化了)。

第19條(B):總是初始設定變數。

    這裡有兩段很好的範例程式碼:

// 雖然正確但不可取的方式:定義變數時沒有初始化int speedupFactor;if (condition)    speedupFactor = 2;else    speedupFactor = -1;

以下兩種方式更好一些:

// 可取的方式一:定義變數時即初始化int speedupFactor = -1;if (condition)    speedupFactor = 2;  // 較好且簡練的方式二:定義變數時即初始化int speedupFactor = condition ? 2 : -1;

 

第20條(D):避免函數過長,避免嵌套過深

第21條(C):避免跨編譯單元的初始化依賴

第22條(A):盡量減少定義性依賴。避免循環相依性。

    儘可能的使用前置聲明(forward declaration). Pimpl慣用法對遵循這一規範有實際性的協助。DIP(依賴倒置原則)。

第23條(A):標頭檔應該自給自足

   各司其責:應該確保每個標頭檔都能夠單獨編譯。

第24條(A):總是編寫內部的#include保護符,決不要編寫外部的#include保護符

函數與操作符

第25條(B):正確地選擇通過值、(智能)指標或者引用傳遞參數

第26條(C):保持重載操作符的自然語義

第27條(C):優先使用算術操作符和賦值操作符的標準形式

     1)如果要定義 a+b,也應該定義 a+=b。一般利用後者實現前者,即賦值形式的操作符完成實際的工作,非賦值形式的操作符調用賦值形式的操作符。2)如果可能,優先選擇將這些操作符函數定義為非成員函數,並將其和要類型T放入同一個名字空間中。3)非成員函數傳回值或引用,成員函數返回引用。

帖幾段範例程式碼:

// 成員函數 @= T& operator@=(const T& rhs){     //.....具體的實現代碼.....     return *this;}// 非成員函數 @ T  operator@(const T& lhs, const T& rhs){T temp = lhs;return temp @= rhs;}// 非成員函數 @= 返回輸入參數的引用T& operator@=(T& lhs, const T& rhs){    // ......具體的實現代碼......    return lhs; // 返回輸入參數的引用}// 非成員函數 @ T operator@(T lhs, const T& rhs){    return lhs @= rhs;}

 

第28條(A):優先使用++和--的標準形式。優先使用首碼形式
      如果定義了++C,也應該定義 C++,而且應該用首碼形式實現尾碼形式。

標準形式,範例程式碼:

//  首碼形式T& operator++(){    // ......執行遞增的實現代碼   return *this; // 返回遞增後的新值} // 尾碼形式T operator++(int) // 傳回值{     T oldT(*this); // 先儲存原值      ++(*this);  // 調用首碼形式執行遞增      return oldT; //  返回原值}

 

第29條(D):考慮重載以避免隱含類型轉換

第30條(A):避免重載操作符&&, || 和,(逗號)

第31條(A):不要編寫依賴於函數參數求值順序的代碼

     調用函數時,參數的求值順序是懸而未定的。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.