編程規(guī)范
1禁止在頭文件中定義變量
2禁止在extern “C”中包含頭文件,否則會導致extern “C”嵌套,嵌套太多導致編譯錯誤
3每個模塊提供多個.c文件,在同一目錄下,目錄名為模塊名,并提供一個.h文件
4.如果一個模塊包含多個模塊,則每個模塊提供一個.h文件名為子模塊名
5.頭文件排版方式:1.按字母升序
??????????????????????????? ?2.將不穩(wěn)定(常修改)的放在前面
6.一個函數(shù)僅完成一項功能。重復(fù)代碼盡量寫成函數(shù)
7.避免函數(shù)過程,最好不超過50行。
8.代碼嵌套不超過4層
9.函數(shù)不變參數(shù)要寫為const
10.避免使用全局變量和靜態(tài)變量
11.函數(shù)參數(shù)個數(shù)不超過5個。檢查參數(shù)的有效性(是否為NULL)
12.命名規(guī)則
l???????? unix風格:每個單詞小寫,并用下劃線分開my_name
l???????? windows風格:每個單詞首字母大寫 MyName
l???????? 文件命名采用小寫字符
l???????? 全局變量g_??? 靜態(tài)變量s_
(5)宏:大寫單詞_大寫單詞
13:將宏定義的放在大括號內(nèi)
14:用const替代宏定義
15.inline函數(shù)的優(yōu)點:
l???????? 編譯時不用展開,代碼Size小,
l???????? 可以加斷電,易于定位問題。例如對于引用計數(shù)加減的時候
l???????? 編譯時編譯器做語法檢查
16.注釋在代碼上面(用空行隔開)或右邊
?
17
文件頭注釋:
/**
*@file?? ?????? 文件名
*@brief?? ???? 功能描述
*@version? ?版本
*@author?????? ?? ?作者
*@date ? ????創(chuàng)建日期
*/
?
函數(shù)頭注釋:
/**
*@descriotion
*@param a
*@param b
*@return c
*/
?
18程序塊采用縮進風格編寫,每級縮進為4個空格。
19相對獨立的程序塊之間、變量說明之后必須加空行
20.一條語句不能過長,拆分
l???????? 換行時要增加一級縮進
l???????? 低優(yōu)先級操作符處劃分新行;換行時操作符應(yīng)該放下來放在新行首
l???????? 換行時一個完整的語句放在一行
l???????? 一行只寫一條語句
21.兩個以上的關(guān)鍵字、變量、常量進行對等操作時,操作符前后應(yīng)該加空格
l???????? 符號、操作符后面加空格
l???????? if、for、while、switch后加空格。
l???????? !、~、++、--、&后不加空格
l???????? 注釋符與注釋內(nèi)容之間加空格
?
22一組相關(guān)的整數(shù)用enum
23.不相關(guān)的常量,即使取值相同,也必須分別定義
24變量使用時才聲明并初始化
25.避免構(gòu)造函數(shù)做復(fù)雜的初始化,
可以使用init函數(shù)():
l???????? 需要提供初始化返回信息
l???????? 數(shù)據(jù)成員初始化可能拋異常
l???????? 數(shù)據(jù)成員初始化失敗會造成該類對象初始化失敗,引起不確定狀態(tài)
l???????? 數(shù)據(jù)成員初始化依賴this指針:構(gòu)造函數(shù)沒結(jié)束,對象就沒有構(gòu)造出來,構(gòu)造函數(shù)內(nèi)不能使用this成員
l???????? 數(shù)據(jù)初始化需要調(diào)用虛函數(shù)。在構(gòu)造函數(shù)和西溝函數(shù)中調(diào)用虛函數(shù),會導致未定義行為。
26初始化列表嚴格按照成員聲明順序初始化
27.使用c++風格的類型轉(zhuǎn)換
const_cast 移除const屬性的轉(zhuǎn)換。避免使用
dynamic_cast下行轉(zhuǎn)換,基類指針轉(zhuǎn)換為子類指針。類型檢查,建議調(diào)試代碼中使用
static_cast 一般的強制轉(zhuǎn)換
reinterpret_cast 轉(zhuǎn)換不相關(guān)的類型,避免使用。
28.內(nèi)聯(lián)函數(shù)小于10行。且不要有循環(huán)、遞歸、虛函數(shù)。內(nèi)聯(lián)函數(shù)在頭文件中聲明
29.盡量用const引用取代指針。引用比指針安全,一定非空,一定不會指向其他目標。不需要檢查非法NULL指針
30,一定要寫構(gòu)造函數(shù)。
構(gòu)造函數(shù)參數(shù)列表的初始化
Message():
a(0),
b(“”),
c(NULL)
{
}
30.如果不定義構(gòu)造、拷貝、賦值、析構(gòu)等。編譯器會自動生成。
默認的構(gòu)造和賦值函數(shù)只是將元對象的成員簡單賦值給目的對象,即淺拷貝(shallow copy)。使元對象和目的對象的成員指向同一內(nèi)存,導致資源重復(fù)釋放。自動生產(chǎn)的析構(gòu)函數(shù)是空的,不能釋放已盛情的堆內(nèi)存。如果不需要拷貝夠咱函數(shù)和賦值函數(shù),將其聲明為private
31..讓operator=返回*this的引用,使之能連等。并檢查是否是自賦值
String&String::operator=(const String &rhs)
{
???? If(this!=&rhs)
{
???????? delete [] data;
???????? data=new char[strlen(rhs.data)+1];
???????? strcpy(data,rhs.data);
}
return *this;
}
?
32基類指針執(zhí)行刪除操作時,基類的析構(gòu)函數(shù)設(shè)為共有虛擬的。保障派生類析構(gòu)函數(shù)被調(diào)用
33虛函數(shù)不使用默認參數(shù),因為是動態(tài)綁定的,而默認參數(shù)是編譯時靜態(tài)綁定的,所以最終執(zhí)行的函數(shù)是一個定義在派生類,但卻使用了基類的默認參數(shù)值的虛函數(shù)
?
class A
{
?
public:
?? virtual void display(const string& str="Base")
?? {
????? cout<<str<<endl;
?? }
};
class B:public A
{
public:
?? virtual void display(const string& str="Derived")
?? {
?? cout<<str<<endl;
?? }
};
?
A* a=new B();
a->display();//調(diào)用派生類display,調(diào)用基類默認形參,輸出Base,
delete a;
a=NULL;
?
34.絕不重新定義(隱藏)繼承而來的非虛函數(shù)。因為無法動態(tài)綁定
35.避免派生類中定義與基類同名但參數(shù)類型不同的函數(shù),引起虛函數(shù)調(diào)用失敗
36.派生類重定義的虛函數(shù)也要聲明virtual
37.僅在輸入?yún)?shù)類型不同個,功能相同時重載函數(shù)
?
38建議4.7 使用重載以避免隱式類型轉(zhuǎn)換
說明:隱式轉(zhuǎn)換常常創(chuàng)建臨時變量;如果提供類型精確匹配的重載函數(shù),不會導致轉(zhuǎn)換。
示例:
class String?
{
??? //…
??? String( const char* text );????? //允許隱式轉(zhuǎn)換
};
bool operator==( const String&, const String& );
//…代碼中某處…
if( someString == "Hello" ) {... }
上述例子中編譯器進行隱式轉(zhuǎn)換,好像someString == String( "Hello")一樣,形成浪費,因為并不需
要拷貝字符。使用操作符重載即可消除這種隱式轉(zhuǎn)換:
bool operator==( const String& lhs, const String& rhs );???? //#1
bool operator==( const String& lhs, const char* rhs );?????? //#2
bool operator==( const char* lhs, const String& rhs );?????? //#3
?
39使用名字空間進行歸類,避免符號沖突cout<<space_a::a+space_b::a;
40不要在頭文件中或者#include之前使用using指示符
?
41不要在extern "C"內(nèi)部使用#include包含其他頭文件
在C++代碼中調(diào)用C的庫文件,需要用extern "C"來告訴編譯器:這是一個用C寫成的庫文件,用C的方式來鏈接它們。
嚴格的講,只應(yīng)該把函數(shù)、變量以及函數(shù)類型這三種對象放置于extern "C"的內(nèi)部。
如果把#include指令放在extern "C"里面,可能會導致extern "C"嵌套而帶來如下幾個風險:
extern "C"嵌套過深,導致編譯錯誤
extern "C"嵌套后,改變其他某些文件的編譯鏈接方式
?
42構(gòu)造函數(shù)初始化列表在同一行或按4格縮進并排幾行
43類的聲明按照一定的次序和規(guī)范進行。建議的次序如下:
?? 按照存取控制特性段排序:public、protected、private,如果沒有可以忽略。這個排序是讓聲
明的時候使用者首先看到最關(guān)心的特性(對外接口)。
?? 在每一段中按照如下順序聲明(先定義后續(xù)用到的類型,常量和enums;然后定義行為(構(gòu)造,析構(gòu),
成員函數(shù)),最后定義成員變量):
1.? typedefs和enums;
2. 常量;
3. 構(gòu)造函數(shù);
4. 析構(gòu)函數(shù);
5. 成員函數(shù),含靜態(tài)成員函數(shù);
6. 數(shù)據(jù)成員,含靜態(tài)數(shù)據(jù)成員。
?
44 使用‘//’注釋方式,而不是‘/* */',容易產(chǎn)生交叉錯亂
?
45不直接使用C++的基本數(shù)據(jù)類型,不要假定其存儲尺寸長度
說明: C++標準沒有明確基本數(shù)據(jù)類型的大小與存儲格式,? 這些基本類型包括: short,? int, long, lo
long, float double等。這些基本數(shù)據(jù)類型在不同的編譯器中,實現(xiàn)有所不同,如:
long類型在32位編譯模式下為4字節(jié)長度,在64位編譯模式下為8字節(jié)長度。
所以建議不要直接使用基本數(shù)據(jù)類型。推薦如下兩種使用方式:
1、重定義基本數(shù)據(jù)類型
typedef int32_t int;
typedef int64_t long long;