C++編碼規範

1,類型名的第一個字母大寫,最後以_T結尾

2,變量和函數名首字母小寫,其後每一個單詞的首字母大寫,其它小寫。

3,全大寫的函數名,和小寫的函數名一樣,不過是增加了錯誤處理而已,編譯時用inline實現。

4,指針用p開頭或者用Ptr結尾。

5,用前綴區分作用域:i_ (instance scope)、c_ (class scope)、g_ (global scope)、f_ (file scope)。yathing:不加下劃線,表示數據類型,m_ 表示成員變量,等等......

6,全大寫的前綴,表示項目名、Packet或者Library等(命名空間級別以上)。

7,用可發音的名字。

8,詞彙通用、通俗、但是避免誤解。

9,lhs,函數左值參數;rhs,函數右值參數。

10,a、an、any區分重名參數。

11,指針和引用的區別關鍵:NULL是不是合法值。

12,無符號、位操作,慎用。效率低下、兼容性問題等。

13,內置數據類型傳值、非內置類型傳引用(首選)或指針。

14,若不得不使用參數不確定的函數,用<stdarg.h>提供的方法[1]。

15,若必須返回值,不要強行返回引用[2]。

16,禁止成員函數返回成員的引用或指針,只讀的例外[3]。

17,顯示禁止編譯器自動生成不需要的函數[4]。

18,絕不要重新定義繼承來的非虛函數。

19,絕不要重新定義缺省參數值。

20,多重繼承的基類析構函數都應該是虛函數。

21,純虛函數:只繼承接口並且派生類必須提供實現。一般虛函數:繼承接口並提供缺省實現。

22,類型差異不影響行爲時,用模板,否則用繼承。

23,誰申請誰釋放[5]。

24,關於虛友元函數[6]。

25,關於虛構造函數[7]。

26,不要用構造函數初始化靜態成員。

27,包含資源管理的類應自定義拷貝、賦值、析構函數。

28,拷貝構造、賦值、析構函數要麼全自定義,要麼全生成。

29,循環隊列的問題常出現在:插入元素使得下標從MAX-1繞回0,刪除元素使得下標從0繞回到MAX-1,插入頭一兩個元素,以及刪除最後一兩個元素時。如果我們將隊首設在MAX-3處,可以將這些情況全覆蓋住。

30,任何變量和成員函數,首選const修飾。

31,確保自定義操作符能和其它操作符混合使用[8]。

32,顯式轉換而不是隱式

33,自定義類提供asInt()這樣的顯式轉換而不是隱式轉換函數int operator int(void)

34,用關鍵字explicit防止單參數構造函數的類型轉換功能[9]。

35,模板的使用如果有限制條件,一定要在註釋和文檔中描述清楚。

36,嵌套template的>>中間要加空格以區別operator >>

37,在循環過程中不要修改循環計數器。

38,不能用goto跳出、跳入循環體,不能用goto跳出、跳入程序塊。

39,用inline代替宏函數、用typedef代替類型定義、用const常數代替宏常數

40,每一行不超過78個字符

41,case若不需要break則一定要加註釋聲明

42,註釋完善代碼,而不是重複代碼(最簡單的:這麼做是爲了什麼)

43,用#if 0而不是/**/註釋掉大段的代碼

44,註釋不能超出被註釋代碼所包含的內容[10],這個毛病初學者常犯——把註釋當文檔用了。

45,註釋中避免引用容易變化的信息

46,註釋下限:每5行代碼至少一行註釋;沒聽說過有上限。

47,該用volatile時一定要用[11]。

ps:本書後面還有附錄代碼,以示例的形式展現各條編程規範。因爲時間緣故,就不作整理了吧!^_^

 

[1] <stdarg.h>中定義的宏提供了一種安全有效的訪問參數鏈的方法。

[2] 相應的例子,參見《返回值和返回引用》

[3] 和Jal商量了一會兒,我們的意見是:指針的效率慢,所以儘量用引用(能夠用的場合實在不算太多,類裏面返回引用,最好還要加const)。但是引用實在是很容易令人犯錯,算是仁者見仁、智者見智吧!

[4] 比如,聲明拷貝構造函數、賦值函數,防止友元使用或者定義。

[5] 利用引用計數,每次拷貝或賦值的時候都只是將引用數加1,而在每個引用計數對象析構的時候引用計數減1,只有當引用計數爲0時才調用析構函數。計算機中使用引用計數的應用很多,如:多用戶打開同一個文件、內存頁面的引用等。

[6] C++語法不允許(非成員的)友元函數爲虛函數,不過我們可以通過編程技巧達到虛友元想達到的效果。

  1. /************************************************************************/
  2. /* 一般情況下基類和派生類都要加入友元operator<<打印輸出,
  3. 我們這裏卻採用虛函數print輸出(相當於完成友元功能的虛函數)             */
  4. /************************************************************************/
  5. class Base_T
  6. {
  7. public:
  8.     virtual void print(ostream&){}
  9. };
  10. class Derived :public Base_T
  11. {
  12. public:
  13.     virtual void print(ostream&){}
  14. };
  15. //它不是任何類的友元,只需要帶基類引用作爲第二個參數即可。
  16. ostream& operator<<(ostream& output,Base_T& anObject)
  17. {
  18.     anObject.print();
  19. }

[7] C++語法不允許構造函數爲虛函數,但有時又需要這樣的函數:它們能夠根據不同情況構造出不同的派生類,這類函數實際起到虛構造函數的作用。參見下面的代碼:

  1. class Base_T
  2. {
  3. public:
  4.     //根據自身this類型,克隆出一個新對象
  5.     virtual Base_T& clone(void);
  6. };
  7. Base_T& baseRef = aDrivedObj;
  8. Base_T& anotherBaseRef = aDerivedObj.clone();

[8] operator ^()被重定義後,x^y+b會被解釋爲x^(y+b),而不是所希望的(x^y)+b,因爲編譯器是按異或的優先級確定運算順序的。

[9] 單參數構造函數的一個隱含意思是:將該參數轉換成該類的一個對象。explicit則用來禁止編譯器隱式調用該構造函數,以防止隱式的類型轉換。

[10]

  1. 沒必要說二叉樹,此處代碼不包括實現細節。
  2. //Search the set for the item using a binary-tree search algorithm
  3. bool contains(Item anItem);
  4. 恰當
  5. //Return true if the specified item is contained in the root
  6. bool contains(Item anItem);

[11] 關鍵字volatile的含義是:其所修飾的變量的值可能會發生變化(比如中斷程序修改該變量),而這種變化是編譯器察覺不到的。例子:

  1. char c = ioRegisters.input;//應該用volatile修飾ioRegisters.input
  2. c=ioRegisters.input;//否則編譯器優化時可能刪掉此句

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章