Google C++程式設計規範
1 標頭檔案
1.1 #define的保護
有標頭檔案都應該使用#define防止標頭檔案被多重包含( multiple inclusion) ,命名格式應當是:<PROJECT>_<PATH>_<FILE>_H_
。為保證唯一性,標頭檔案的命名應基於其所在專案原始碼樹的全路徑。例如,專案foo中的標頭檔案foo/src/bar/baz.h按如下方式保護:
#ifndef FOO_BAR_BAZ_H_
#define FOO_BAR_BAZ_H_
...
#endif // FOO_BAR_BAZ_
1.2 行內函數
只有當函式只有10行甚至更少時才會將其定義為行內函數
1.3 函式引數順序
定義函式時,引數順序為:輸入引數在前,輸出引數在後
1.4 包含檔案的名稱和次序
次序如下: C庫、 C++庫、 其他庫的.h、 專案內的.h
2 建構函式
2.1 建構函式的職責
建構函式中只進行那些沒有實際意義的( 簡單初始化對於程式執行沒有實際的邏輯意義, 因為成員變數的“有意義”的值大多不在建構函式中確定)初始化, 可能的話,使用Init()方法集中初始化為有意義的資料。
2.2 明確的建構函式
對於單引數建構函式使用C++關鍵字explicit
2.3 結構體和類
僅當只有資料時使用struct,其它一概使用class
2.4 繼承
- 所有的繼承必須是public
- 資料成員應該始終為private
- 含有虛擬函式的父類中,定義虛解構函式絕對必要
- 當重定義派生的虛擬函式時, 在派生類中明確宣告其為virtual
2.5 介面
介面類即為抽象類,聲明瞭純虛擬函式,不能被直接例項化,其解構函式必須宣告為虛擬函式。一般以Interface為字尾命名。
2.6 操作符過載
除少數特定情況下,不要過載操作符
2.7 存取控制
- 將資料私有化,並提供相關的存取函式
- 存取函式的定義一般內聯的標頭檔案中
2.8 宣告次序
先public再protected最後private
每一塊中的宣告次序如下:
- typedefs和enums;
- 常量;
- 建構函式;
- 解構函式;
- 成員函式,含靜態成員函式;
- 資料成員,含靜態資料成員
3 其他C++特性
3.1 引用引數
按引用傳遞的引數必須加上const
3.2 預設引數
禁止使用預設函式引數
3.3 型別轉換
命名用static_cast<>()等C++的型別轉換, 不要使用 int y = (int)x或 int y = int(x)
- static_cast: 和C風格轉換相似可做值的強制轉換, 或指標的父類到子類的明確的向上
轉換; - const_cast:移除const屬性
3.4 前置自增和自減
迭代器和模板型別來說,要使用前置自增(自減),效率更高
3.5 const的使用
強烈建議在任何可以使用的情況下都要使用const
- 如果函式不會修改傳入的引用或指標型別的引數,這樣的引數應該為const
- 儘可能將函式宣告為const,訪問函式應該總是const,其他函式如果不會修改任何資料成員也應該是const,不要呼叫非const函式,不要返回對資料成員的非const指標或引用
3.6 整型
- C++內建整型中, 唯一用到的是int, 如果程式中需要不同大小的變數, 可以使用<stdint.h>中的精確寬度( precise-width) 的整型,如int16_t
- 使用斷言宣告變數為非負數,不要使用無符號型
3.7 預處理巨集
使用巨集時要謹慎,儘量以行內函數、列舉和常量代替之
3.8 0和NULL
整數用0,實數用0.0,指標用NULL,字元(串)用’\0’
3.9 sizeof
儘可能用sizeof(varname)代替sizeof(type)
4 命名約定
4.1 檔名命名
檔名要全部小寫,可以包含下劃線( _)或短線( -),按專案約定來
my_useful_class.cpp
my-useful-class.cpp
myusefulclass.cpp
對於包含大量內聯程式碼的類,可以有三個檔案
url_table.h //The class declaration
url_table.cpp // The class definition.
url_table-inl.h // Inline functions that include lots of code
4.2 型別命名
- 型別命名每個單詞以大寫字母開頭,不包含下劃線: MyExcitingClass、 MyExcitingEnum。
- 所有型別命名——類、結構體、型別定義( typedef)、列舉——使用相同約定,例如:
// classes and structs
class UrlTable { ...
class UrlTableTester { ...
struct UrlTableProperties { ...
// typedefs
typedef hash_map<UrlTableProperties *, string> PropertiesMap;
// enums
enum UrlTableErrors { ...
4.3 變數命名
變數名一律小寫,單詞間以下劃線相連,類的成員變數以下劃線結尾,如my_exciting_local_variable、 my_exciting_member_variable_。
string table_name; // OK - uses underscore.
string tablename; // OK - all lowercase.
string tableName; // Bad - mixed cas
4.4 常量命名
在名稱前加k: kDaysInAWeek
4.5 函式命名
- 普通函式:
函式名以大寫字母開頭,每個單詞首字母大寫,沒有下劃線:
AddTableEntry()
DeleteUrl() - 存取函式:
存取函式要與存取的變數名匹配,這兒摘錄一個擁有例項變數num_entries_的類:
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_;
};
- 其他短小的行內函數名也可以使用小寫字母
4.6 名稱空間
名稱空間的名稱是全小寫的,其命名基於專案名稱和目錄結構: google_awesome_project
4.7 列舉命名
- 列舉值應全部大寫,單詞間以下劃線相連: MY_EXCITING_ENUM_VALUE。
- 列舉名稱屬於型別,因此大小寫混合: UrlTableErrors。
enum UrlTableErrors {
OK = 0,
ERROR_OUT_OF_MEMORY,
ERROR_MALFORMED_INPUT,
}