小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

c/c++語言規(guī)范

 Frank_Chia 2009-09-27

­­­  一、背景

每一個(gè)C++程序員也都知道,C++具有很多強(qiáng)大的語言特性,但這種強(qiáng)大不可避免的導(dǎo)致它的復(fù)雜,而復(fù)雜性會(huì)使得代碼更容易出現(xiàn)bug、難于閱讀和維護(hù)。

 

本規(guī)范的目的是通過詳細(xì)闡述如何進(jìn)行C++來規(guī)避其復(fù)雜性,使得代碼在有效使用C++語言特性的同時(shí)還易于管理。

 

C++包含大量高級(jí)特性的巨型語言,某些情況下,我們會(huì)限制甚至禁止使用某些特性使代碼簡化,避免可能導(dǎo)致的各種問題。

 

二、命名規(guī)范

 

(一)通用命名規(guī)則

1、類型名

類型名(類、結(jié)極體、類型定義(typedef)、枚舉)以大寫字母開始并混合大小寫,如

 

Line, SavingsAccount

 

2、變量名

變量名必須以小寫字母開始并混合大小寫,

 

line, savingsAccount

 

3、函數(shù)名

函數(shù)名必須以小寫字母的動(dòng)詞開始并混合大小寫,如:

 

getName(), computeTotalWidth()

 

4、常量名

常量名(包括枚舉值)必須全部大寫并以下劃線分隔,如

 

MAX_ITERATIONS, COLOR_RED, PI

 

 

 

5、類的私有變量

類的私有變量必須以下劃線_作為后綴,如:

 

class SomeClass {

 

  private:

 

    int length_;

 

}

 

6、名字空間

名字空間的命名必須全部小寫,如:

 

model::analyzer, io::iomanager, common::math::geometry

 

 

 

7、接口類

接口類的命名以前綴的大寫I后跟類名, 如:

 

class IFoo

 

{

 

public:

 

       virtual ~IFoo(){};

 

       virtual void dooo() = 0;

 

}

 

 

 

8、模板類型名

模板類型命名必須是單個(gè)大寫字母,如:

 

template<class T> ...

 

template<class C, class D> ...

 

9、縮略語

縮略語不必都是大寫,如:

 

exportHtmlSource(); // 這樣不好: exportHTMLSource();

 

openDvdPlayer();    // 這樣不好: openDVDPlayer();

 

 

 

 

 

10、全局變量

   

全局變量命名規(guī)則同變量名,只是全局變量必須總是以::來引用,如:

 

::mainWindow.open(), ::applicationContext.getName()

 

11、通用變量

通用變量(如函數(shù)參數(shù))的命名應(yīng)該就是它的類型,且首字母小寫,如:

 

void setTopic(Topic* topic)  // 這樣不好: void setTopic(Topic* value)

 

                            // 這樣不好: void setTopic(Topic* aTopic)

 

                            // 這樣不好: void setTopic(Topic* t)

 

 

 

void connect(Database* database)  // 這樣不好: void connect(Database* db)

 

                                 // 這樣不好: void connect (Database* oracleDB)

 

 

 

12、文件名

文件名全部小寫,C++文件以.cpp結(jié)尾,頭文件以.h結(jié)尾,文件名與文件里類的名字相同。

 

(二)非通用命名規(guī)則

1、非通用變量(如局部變量)可以是這樣:

 

  Point  startingPoint, centerPoint;

 

  Name  loginName;

 

函數(shù)名中不應(yīng)該再包括對(duì)象名,如:

 

line.getLength();   //這樣不好: line.getLineLength();

 

 

 

(三)特殊命名規(guī)則

1、指針命名:

 

Line* line;   // 這樣不好: Line* pLine;

 

            // 這樣不好: Line* linePtr;

 

 

 

2、枚舉常量可以使用一個(gè)公共的類型名作為前綴,如:

 

enum Color {

 

  COLOR_RED,

 

  COLOR_GREEN,

 

  COLOR_BLUE

 

};

 

 

 

3、bool類型的變量和函數(shù)返回值是bool的函數(shù)以is為前綴來命名,如:

 

isSet, isVisible, isFinished, isFound, isOpen

 

在某些情況下,有些比is前綴更適合(has, can, should),如:

 

  bool hasLicense();

 

  bool canEvaluate();

 

  bool shouldSort();

 

 

 

當(dāng)有屬性的情況下,使用get/set來存取,如:

 

employee.getName();

 

employee.setName(name);

 

matrix.getElement(2, 4);

 

matrix.setElement(2, 4, value);

 

 

 

想要計(jì)算什么可以使用compute,如:

 

valueSet->computeAverage();

 

matrix->computeInverse()

 

 

 

想要想找什么可以使用find, 如:

 

vertex.findNearestVertex();

 

matrix.findMinElement();

 

 

 

對(duì)象的初始化可以使用initialize ,而不要使用init

 

 

 

4GUI組件的命名要把組件類型放到變量的后面,如:

 

mainWindow, propertiesDialog, widthScale, loginText,

 

leftScrollbar, mainForm, fileMenu, minLabel, exitButton, yesToggle 等。

 

 

 

5、復(fù)數(shù)形式變量命名使用如下:

 

vector<Point>  points;

 

int            values[];

 

 

 

變量具有前綴n表明這個(gè)變量代表了對(duì)象的個(gè)數(shù),如:

 

nPoints, nLines

 

 

 

No為后綴的變量表明第幾個(gè)對(duì)象,如:

 

tableNo, employeeNo

 

 

 

5、迭代變量應(yīng)該被命名為i, j, k等,如:

 

for (int i = 0; i < nTables); i++) {

 

  :

 

}

 

for (vector<MyClass>::iterator i = list.begin(); i != list.end(); i++) {

 

  Element element = *i;

 

  ...

 

}

 

 

 

對(duì)稱的命名:

 

get/set, add/remove, create/destroy, start/stop, insert/delete,

 

increment/decrement, old/new, begin/end, first/last, up/down, min/max,

 

next/previous, old/new, open/close, show/hide, suspend/resume, etc.

 

 

 

命名時(shí)避免使用縮略語

 

 

 

禁止否定的bool變量名,如:

 

bool isError;  //這樣不好: isNoError

 

bool isFound;  //這樣不好: isNotFound

 

 

 

6、異常類命名以Exception作為后綴,如:

 

class AccessException

 

{

 

  :

 

}

 

 

 

注:

 

       1) 不要使用匈牙利命名法

 

         2) Windows定義了很多原有內(nèi)建類型的同義詞(很反感,容易導(dǎo)致類型混亂),如DWORD、HANDLE等等,在調(diào)用Windows API時(shí)這是完全可以接受甚至鼓勵(lì)的,但在非調(diào)用API時(shí)盡量使用原來的C++類型,例如,使用const TCHAR *而不是LPCTSTR;原因:有助于代碼的移植。特別是服務(wù)器后臺(tái)開發(fā)人員,盡量使用標(biāo)準(zhǔn)的C++類型。

 

 

 

代碼書寫規(guī)范

C++是個(gè)特性極其豐富而復(fù)雜的語言,本文檔旨在提供如何編寫高質(zhì)量C++程序的建議。

 

原則

正確、簡單和清晰第一

       軟件簡單為美(Keep it Sample Software, KISS原則),正確優(yōu)于速度,簡單優(yōu)于復(fù)雜,清晰優(yōu)于機(jī)巧,安全優(yōu)于不安全。

 

       要避免出現(xiàn)代碼“壞味道”,摘錄自《重構(gòu) 改善既有代碼的設(shè)計(jì)》

 

 

 

代碼的壞味道

1.       重復(fù)代碼

 

2.       過長函數(shù)

 

3.       過大類

 

4.       過長參數(shù)列

 

5.       發(fā)散式變化

 

6.       霰彈式修改

 

7.       依戀情結(jié)

 

8.       數(shù)據(jù)泥團(tuán)

 

9.       基本型別偏執(zhí)

 

10.   switch驚悚現(xiàn)身

 

11.   平等繼承體系

 

12.   冗贅類

 

13.   夸夸其談未來性

 

14.   令人迷惑的暫時(shí)值域

 

15.   過度耦合的消息鏈

 

16.   中間轉(zhuǎn)手人

 

17.   狎昵關(guān)系

 

18.   異曲同工的類

 

19.   不完善的程序庫類

 

20.   純稚的數(shù)據(jù)類

 

21.   被拒絕的遺贈(zèng)

 

22.   過多的注釋

 

 

 

具體內(nèi)容請(qǐng)參考《重構(gòu),改善既有代碼的設(shè)計(jì)》, 在寫代碼的過程中,加紅的幾個(gè)是特別需要注意的

 

 

 

7、編譯設(shè)置

在高警告級(jí)別進(jìn)行編譯,使用VC編譯器應(yīng)將警告級(jí)別打到最高4級(jí),并設(shè)置將警告作為錯(cuò)誤

 

寧要編譯時(shí)和連接時(shí)錯(cuò)誤,而不要運(yùn)行時(shí)錯(cuò)誤

 

項(xiàng)目設(shè)置include, lib路徑使用相對(duì)路徑,不要使用絕對(duì)路徑

 

debug編譯生成的是名稱后加d ,如(debugxxxd.exe, releasexxx.exe

 

 

 

頭文件

正確使用頭文件可令代碼在可讀性、文件大小和性能上大為改觀。

 

頭文件以.h作擴(kuò)展名

 

#define保護(hù)

所有頭文件 都應(yīng)該使用#define防止頭文件被多重包含(multiple inclusion),命名格式為:<PROJECT>_<PATH>_<FILE>_H_

 

為保證唯一性,頭文件的命名應(yīng)基于其所在項(xiàng)目源代碼樹的全路徑。例如,項(xiàng)目foo中的頭文件foo/src/bar/baz.h按如下方式保護(hù):

 

#ifndef FOO_BAR_BAZ_H_

 

#define FOO_BAR_BAZ_H_

 

 ...

 

#endif // FOO_BAR_BAZ_H_

 

注:不要使用#pragma once來防止重復(fù)包含,因?yàn)樵撝噶钍?/span>vc特有的,它是一個(gè)編譯器指令,其它的編譯器不保證能支持它,而#ifndef是語言層面的, 只要是支持c++的編譯器, 都支持,跨平臺(tái),兼容性更好。

 

頭文件依賴

使用前置聲明(forward declarations)盡量減少.h文件中#include的數(shù)量,加快編譯速度。

 

 

 

內(nèi)聯(lián)函數(shù)

叧有當(dāng)函數(shù)叧有10行甚至更少時(shí)才會(huì)將其定義為內(nèi)聯(lián)函數(shù)(inline function)。

 

注:濫用內(nèi)聯(lián)將導(dǎo)致程序變慢。

 

函數(shù)參數(shù)順序

 

定義函數(shù)時(shí),參數(shù)順序?yàn)椋狠斎雲(yún)?shù)在前,輸出參數(shù)在后。

 

包含文件的名稱及次序

將包含次序標(biāo)準(zhǔn)化可增強(qiáng)可讀性、避免隱藏依賴(注:隱藏依賴主要是指包含的文件編譯)

 

頭文件包含次序如下:C庫、C++庫、其他庫的.h、項(xiàng)目內(nèi)的.h

 

實(shí)現(xiàn)文件(dir/foo.cpp)包含次序如下:

 

dir2/foo2.h(優(yōu)先位置,詳情如下)

 

C系統(tǒng)文件

 

C++系統(tǒng)文件

 

其他庫頭文件

 

本項(xiàng)目內(nèi)頭文件

 

在包含文件里不要使用.(當(dāng)前目錄)..(父目錄),如:

 

#include ../abc.h // 不要這樣使用

 

 

 

作用域

命名空間

.cpp文件中,允許甚至提倡使用未具名命名空間,以避免運(yùn)行時(shí)的命名沖突: namespace {

 

 // .cc 文件中 // 命名空間的內(nèi)容無需縮進(jìn)

 

 enum { UNUSED, EOF, ERROR }; // 經(jīng)常使用的符號(hào)

 

bool AtEof() { return pos_ == EOF; } // 使用本命名空間內(nèi)的符號(hào)EOF

 

} // namespace

 

然而,不特定類關(guān)聯(lián)的文件作用域聲明在該類中被聲明為類型、靜態(tài)數(shù)據(jù)成員或靜態(tài)成員函數(shù),而不是未具名命名空間的成員。像上文展示的那樣,不具名命名空間結(jié)束時(shí)用注釋// namespace標(biāo)識(shí)。

 

不能在.h文件中使用未具名命名空間。

 

不要在頭文件中或者#include之前使用using namespace

 

局部變量

 

將局部變量盡可能置于最小作用域內(nèi),在聲明變量時(shí)就將其初始化。

 

全局變量

禁止class類型的全局變量

 

內(nèi)建類型的全局變量是允許的,

 

當(dāng)然多線程代碼中非常數(shù)全局變量也是被禁止的。

 

永遠(yuǎn)不要使用函數(shù)返回值來初始化全局變量。

 

原因:c++標(biāo)準(zhǔn)在全局變量的構(gòu)造函數(shù)、析構(gòu)函數(shù)和初始化順序上沒有保證。因此每次生成都可能會(huì)有變化,從而導(dǎo)致難以覺察的BUGS。

 

對(duì)于全局的字符串常量,使用C風(fēng)格的字符串,而不要使用STL的字符串:

 

const char kFrogSays[] = "ribbet";

 

雖然允許在全局作用域中使用全局變量,使用時(shí)務(wù)必三思。大多數(shù)全局變量應(yīng)該是類的靜態(tài)數(shù)據(jù)成員,或者當(dāng)其叧在.cpp文件中使用時(shí),將其定義到未具名命名空間中

 

注:靜態(tài)成員變量視作全局變量,所以,也不能是class類型!

 

如果一定要使用全局變量,請(qǐng)使用設(shè)計(jì)模式中的單件模式(singleton模式)。

 

C++

用小類代替巨類

構(gòu)造函數(shù)

       類構(gòu)造函數(shù)的初始化列表中成員變量初始化的順序應(yīng)該與在h頭文件中聲明的順序一致。不要在構(gòu)造函數(shù)體里進(jìn)行賦值操作。

 

       對(duì)單參數(shù)構(gòu)造函數(shù)使用C++關(guān)鍵字explicit

 

虛擬函數(shù)

避免在構(gòu)造函數(shù)和析構(gòu)函數(shù)中調(diào)用虛擬函數(shù)

 

 

 

繼承

         多用組合,少用繼承

 

接口

         接口定義如下:

 

class IFoo

 

{

 

public:

 

         virtual ~IFoo(){};

 

         virtual void dooo() = 0;

 

};

 

即含有純虛函數(shù),且實(shí)現(xiàn)虛析構(gòu)函數(shù)的類。

 

接口類主要是為實(shí)現(xiàn)多態(tài)的。

 

 

 

操作符重載

         盡量不要使用操作符重載

 

 

 

存取控制

         將數(shù)據(jù)成員私有化,并提供相關(guān)存取函數(shù)

 

 

 

聲明次序

       在類中使用特定的聲明次序:public:private:之前,成員函數(shù)在數(shù)據(jù)成員(變量)前。

 

定義次序如下:public:、protected:、private:,如果那一塊沒有,直接忽略即可。

 

每一塊中,聲明次序一般如下:

 

1) typedefsenums;

 

2) 常量;

 

3) 構(gòu)造函數(shù);

 

4) 析構(gòu)函數(shù);

 

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

 

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

 

 

 

編寫短小函數(shù)

函數(shù)體盡量短小、緊湊,功能單一

 

 

 

智能指針

       如果確實(shí)需要使用智能指針的話,scoped_ptr完全可以勝任。在非常特殊的情況下,例如對(duì)STL容器中對(duì)象,你應(yīng)該只使用std::tr1::shared_ptr,任何情況下都不要使用auto_ptr

 

 

 

引用參數(shù)

         引用傳遞的參數(shù)必須加上const,如果要將參數(shù)傳出,請(qǐng)使用指針。

 

缺省參數(shù)

禁止使用缺省函數(shù)參數(shù)。

 

異常

不要使用C++異常。

 

異常會(huì)導(dǎo)致程序控制流通過查看代碼無法確定:函數(shù)有可能在不確定的地方返回,從而導(dǎo)致代碼管理和調(diào)試?yán)щy。

 

異常的實(shí)用性可能會(huì)刺激開發(fā)人員在不恰當(dāng)?shù)臅r(shí)候拋出異常,戒者在不安全的地方從異常中恢復(fù)。

 

運(yùn)行時(shí)類型識(shí)別RTTI

禁止使用RTTI, 單元測(cè)試程序除外。

 

 

 

類型轉(zhuǎn)換

使用C++風(fēng)格的類型轉(zhuǎn)換, 不要使用C風(fēng)格的類型轉(zhuǎn)換。

 

1) static_cast:和C風(fēng)格轉(zhuǎn)換相似可做值的強(qiáng)制轉(zhuǎn)換,或指針的父類到子類的明確的向上轉(zhuǎn)換;

 

2) const_cast:移除const屬性;

 

3) reinterpret_cast:指針類型和整型或其他指針間不安全的相互轉(zhuǎn)換,僅在你對(duì)所做一切了然于心時(shí)使用;

 

4) dynamic_cast:除測(cè)試外不要使用,除單元測(cè)試外,如果你需要在運(yùn)行時(shí)確定類型信息,說明設(shè)計(jì)有缺陷(參考RTTI)。

 

前置自增和自減

       對(duì)簡單數(shù)值(非對(duì)象)來說,兩種都無所謂,對(duì)迭代器和模板類型來說,要使用前置自增(自減)。

 

const的使用

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

 

預(yù)處理宏

使用宏時(shí)要謹(jǐn)慎,盡量以內(nèi)聯(lián)函數(shù)、枚舉和常量代替之,字符串化(##)除外;

 

0NULL

         整數(shù)用0,實(shí)數(shù)用0.0,挃針用NULL,字符(串)用'\0';

 

sizeofsizeof

         sizeof(varname)代替sizeof(type);

 

Boost

         只使用Boost中被認(rèn)可的庫。

 

STL容器

默認(rèn)時(shí)使用vector。否則,選擇其他合適的容器

vectorstring代替數(shù)組

使用vector(和string::c_str)與非C++API交換數(shù)據(jù)

在容器中只存儲(chǔ)值和智能指針

push_back代替其他擴(kuò)展序列的方式

算法和比較器的參數(shù)應(yīng)多用函數(shù)對(duì)象少用函數(shù)

 

DLL

分配和釋放內(nèi)存

要避免在不同的模塊中分配和釋放內(nèi)存,例如,在DLL中分配的內(nèi)存,必須仍由該DLL來負(fù)責(zé)釋放,而不要交給調(diào)用該DLL的程序來釋放。

 

全局變量

       不要在DLL中使用全局變量,除非你明確能這樣使用。

 

線程

盡量減少共享數(shù)據(jù)

       在多線程設(shè)計(jì)中,盡量要減少線程間共享的數(shù)據(jù)

 

使用SVN規(guī)范

提交代碼必須寫提交日志

 

提交代碼,代碼必須是debugrelease都可編譯運(yùn)行的

 

在修改代碼之前,首先update

 

 

 

注釋規(guī)范

       本注釋以簡單為主,風(fēng)格遵循doxygen格式,以便于借助doxygen工具可直接生成文檔。

 

注釋的確很重要,但最好的代碼本身就是文檔(自文檔),注釋是為別人(下一個(gè)需要理解你的代碼的人)而寫的,認(rèn)真點(diǎn)吧,那下一個(gè)人可能就是你!

 

注釋風(fēng)格

       統(tǒng)一使用// 來注釋,即雙斜杠 + 空格

文件注釋

       通常,.h文件要對(duì)所聲明的類的功能和用法作簡單說明,.cc文件包含了更多的實(shí)現(xiàn)細(xì)節(jié)或算法討論,如果你感覺這些實(shí)現(xiàn)細(xì)節(jié)或算法討論對(duì)于閱讀有幫助,可以把.cc中的注釋放到.h中,并在.cc中指出文檔在.h中。

 

不要單純?cè)?/span>.h.cc間復(fù)制注釋,復(fù)制的注釋偏離了實(shí)際意義。

 

// @brief 簡要描述

 

// @author 作者

 

類注釋

// 類描述

 

函數(shù)注釋

       // 函數(shù)描述

 

       // @param 參數(shù) 描述

 

       // @return 返回值 描述

 

變量注釋

       注釋占一行, 不要這樣:

 

       Point centerPoint; // 中心點(diǎn)

 

       應(yīng)該這樣:

 

       // 中心點(diǎn)

 

       Point centerPoint;

 

 

 

TODO注釋

         // TODO(開發(fā)者英文名) 內(nèi)容

 

頭文件示例:

 

 

// $Id: something.h 1 2009-08-20 10:56:07 Zhangwenlong $

 

// @brief 頭文件簡要描述

 

// @author 作者

 

 

 

#ifndef SOMETHING_H_

 

#define SOMETHING_H_

 

 

 

// 盡量用前置聲明,以下是為了演示命名規(guī)范

 

// 盡量在頭文件里少包含文件,以免影響編譯速度

 

#include <標(biāo)準(zhǔn)庫.h>

 

#include "第三方庫.h"

 

#include "本項(xiàng)目.h"

 

// 命名空間全部小寫

 

namespace utility

 

{

 

 

struct Point

 

{

 

// 公共變量最后不加下劃線_

 

int x;

 

int y;

 

};

 

enum Color

 

{

 

COLOR_RED,

 

COLOR_WHITE

 

};

 

 

 

// 接口定義如下:

 

class IFoo

 

{

 

public:

 

virtual ~IFoo(){};

 

virtual void doSomething(void) = 0;

 

};

 

// 類命名規(guī)則:首字母大寫

 

class SomeThing

 

{

 

// 如下各塊聲明順序如下:

 

// typedefs

 

// enums

 

// 常量

 

// 構(gòu)造函數(shù)

 

// 析構(gòu)函數(shù)

 

// 成員函數(shù)

 

// 成員變量

 

public:

 

explicit SomeThing(int value);

 

 

 

// 函數(shù)名首字母小寫, 參數(shù)為:輸入在前,輸出在后

 

// 函數(shù)描述

 

// @param 參數(shù) 描述

 

// @return 返回值 描述

 

void doSomething(const Color& color, Point* point);

 

 

 

const std::string& getName(void) const;

 

protected:

 

private:

 

typedef std::vector<Point> Points;

 

// 顏色

 

Color color_;

 

Points points_;

 

bool isDone_;

 

};

 

}

 

#endif // SOMETHING_H_

 

 

CPP文件示例:

// $Id: something.cpp 1 2009-08-20 10:56:29 Zhangwenlong $

 

// @brief cpp文件簡要描述

 

// @author 作者

 

#include "something.h"

 

#include <c系統(tǒng)文件>

 

#include <c++系統(tǒng)文件>

 

#include <其他庫文件>

 

#include "本項(xiàng)目內(nèi)頭文件"

 

 

 

// 可使用匿名命名空間

 

namespace

 

{

 

// 常量定義

 

static const float PI = 3.14;

 

 

 

// 全局函數(shù)

 

static void foo()

 

{

 

// 引用全局變量

 

float pi = ::PI;

 

}

 

 

 

} // namespace

 

SomeThing::SomeThing(int value)

 

:color_(COLOR_RED), points_(), isDone_(false)

 

{

 

}

 

void SomeThing::doSomething(const Color& color, Point* point)

 

{

 

Point centerPoint;

 

// ...

 

}

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多