用c++開發(fā)一款商業(yè)產(chǎn)品誓琼,需要哪些規(guī)范

最近開始接手項(xiàng)目組的開發(fā)管理工作检激,項(xiàng)目組開發(fā)的產(chǎn)品一期功能基本開發(fā)完成,進(jìn)入內(nèi)部測(cè)試及小渠道發(fā)布階段腹侣,然而產(chǎn)品的穩(wěn)定性還存在很大問(wèn)題叔收。

先做一下背景介紹,項(xiàng)目組開發(fā)的是一款面向C端的互聯(lián)剛產(chǎn)品傲隶,運(yùn)行操作系統(tǒng)為windows饺律。整個(gè)項(xiàng)目使用c++開發(fā),總體代碼量大概在數(shù)十萬(wàn)行跺株。

c++是一門很復(fù)雜的語(yǔ)言复濒,有很多強(qiáng)大的特性脖卖,然而當(dāng)用其開發(fā)一款商業(yè)產(chǎn)品時(shí),這些特性可能會(huì)帶來(lái)麻煩巧颈。所以當(dāng)設(shè)計(jì)c++的使用規(guī)范時(shí)胚嘲,更多的是對(duì)其做減法。

本文的規(guī)范針對(duì)VC++開發(fā)環(huán)境洛二,開發(fā)工具為Visual Studio。

文件系統(tǒng)目錄規(guī)范

一款完整的商業(yè)產(chǎn)品開發(fā)通常會(huì)涉及到很多模塊攻锰,這其中包括可執(zhí)行程序(.exe)晾嘶,項(xiàng)目組開發(fā)的庫(kù)(靜態(tài)庫(kù)或動(dòng)態(tài)庫(kù)),第三方的庫(kù)(靜態(tài)庫(kù)或動(dòng)態(tài)庫(kù))娶吞,測(cè)試程序垒迂,這么多的模塊和代碼,需要一個(gè)良好組織的目錄結(jié)夠妒蛇。
這里假設(shè)項(xiàng)目名稱為XXProject

  • XXProject
    • XXProject.sln
    • Bin
      • Debug
      • Release
    • TestBin
    • Debug
    • Release
    • Src
    • Document

其中Bin存放需要發(fā)布的可執(zhí)行程序机断,TestBin存放測(cè)試程序的可執(zhí)行文件,Src存放項(xiàng)目的工程文件和源代碼绣夺,Document存放項(xiàng)目相關(guān)的開發(fā)文檔(如項(xiàng)目說(shuō)明吏奸,代碼規(guī)范等)。

接下來(lái)假設(shè)項(xiàng)目包括如下工程:XXMain(發(fā)布的主程序)陶耍,XXUpdate(升級(jí)程序)奋蔚,XXSdk(自己開發(fā)的基礎(chǔ)庫(kù)),XXThird(第三方庫(kù)), XXTest(測(cè)試程序)

  • Src
    • XXMain
    • XXMain.vcxproy
    • code文件
    • XXUpdate
    • XXUpdate.vcxproy
    • code文件
    • XXTest
    • XXTest.vcxproy
    • code文件
    • XXSdk
    • XXSdk.vcxproy
    • code文件
    • ThirdLib
    • XXThird
    • Lib
    • Debug
    • Release
    • Include
      Lib庫(kù)用來(lái)存放靜態(tài)庫(kù)烈钞,動(dòng)態(tài)庫(kù)的.a文件泊碑,Include用來(lái)存放公共頭文件,ThirdLib用來(lái)存放第三方庫(kù)毯欣。

解決方案目錄規(guī)范

解決方案目錄是VS開發(fā)工具提供的邏輯上組織項(xiàng)目的方式馒过,與物理文件系統(tǒng)并不存在對(duì)應(yīng)關(guān)系。
仍然假設(shè)項(xiàng)目包含上述項(xiàng)目和模塊酗钞。

  • Solution (解決方案)
    • Application (解決方案文件夾)
    • XXMain (工程)
    • XXUpdate (工程)
    • Test (解決方案文件夾)
    • XXTest (工程)
    • Library (解決方案文件夾)
    • XXSdk
    • ThirdLibrary(解決方案文件夾)
    • XXThird
    • Public (解決方案文件夾)
    • 公共頭文件

代碼編寫規(guī)范

1:禁用全局變量

全局變量會(huì)帶來(lái)晦澀的依賴問(wèn)題

2:禁用goto指令

goto指令的代碼難以閱讀和維護(hù)

3:禁用異常機(jī)制

c++的異常機(jī)制有很多缺陷且復(fù)雜

4:用struct封裝數(shù)據(jù)腹忽,使用class定義對(duì)象

C++中class和struct幾乎沒(méi)有區(qū)別,在規(guī)范中進(jìn)行語(yǔ)義的區(qū)分

5:struct和class必須顯示包含構(gòu)造函數(shù)
6:除非特殊情況算吩,總是將析構(gòu)函數(shù)定義為虛函數(shù)

方便繼承時(shí)的資源釋放

7:不要在構(gòu)造函數(shù)中執(zhí)行復(fù)雜操作留凭,推薦加入init函數(shù)用于初始化操作

構(gòu)造函數(shù)沒(méi)有返回值,難以反饋錯(cuò)誤

8:不要在構(gòu)造函數(shù)中調(diào)用虛函數(shù)

構(gòu)造函數(shù)中的虛函數(shù)不會(huì)重定向到子類偎巢。

9:慎用繼承

相比對(duì)象組合蔼夜,繼承帶來(lái)更強(qiáng)的依賴,推薦使用接口繼承而不是對(duì)象繼承

10:禁用多重繼承(接口繼承除外)

多重繼承通常代表不好的設(shè)計(jì)

11:慎用運(yùn)算符重載

運(yùn)算符重載會(huì)混淆代碼的語(yǔ)義压昼,應(yīng)只在不會(huì)造成混淆時(shí)使用

12:將成員設(shè)置為私有并提供訪問(wèn)函數(shù)

封裝是降低代碼耦合的有力武器

13:將同一訪問(wèn)權(quán)限的成員定義在一起

可以按照public,protect,private順序進(jìn)行組織

14:避免出現(xiàn)大而全的類

當(dāng)一個(gè)類的代碼超過(guò)1000行求冷,應(yīng)有所警惕瘤运,超過(guò)2000行,則應(yīng)考慮拆分(行數(shù)不包括注釋)

15:頭文件應(yīng)包含它所需要的頭文件

這樣可以保證cpp文件引入該頭文件后不需要包含其它頭文件

16:合理的組織引入的頭文件匠题,不要重復(fù)引入拯坟,不要引入不必要的頭文件

可以以系統(tǒng)頭文件,第三方庫(kù)頭文件韭山,項(xiàng)目組庫(kù)頭文件郁季,本程序頭文件來(lái)組合,不同類型頭文件之間用空格隔開

17:頭文件使用#define宏來(lái)避免多重包含

pragma once 指令只有VC編譯器能識(shí)別

18:允許合理的使用友元特性

19:使用引用傳遞對(duì)象類型參數(shù), 對(duì)于不需要改變的參數(shù)加入const修飾符

引用傳遞可以避免對(duì)象拷貝

20:函數(shù)應(yīng)該進(jìn)參在前钱磅,出參在后

21:使用明確的返回值指示函數(shù)的運(yùn)行結(jié)果梦裂,而不是用返回的內(nèi)容來(lái)指示結(jié)果

推薦: int GetDeviceName(string& deviceName);
不推薦: string GetDeviceName()

22:聲明基本類型變量后立即賦值

正確 int nCount = 0; bool bSuc = false; 錯(cuò)誤 int nCount; bool bsuc;

23:使用內(nèi)聯(lián),枚舉,常量來(lái)代替宏

宏的使用有很多弊端,應(yīng)盡量避免

24:使用singleton模式代替靜態(tài)類

相比靜態(tài)類后专,singleton模式可以更好地控制初始化時(shí)機(jī)。

25:使用share_ptr來(lái)管理指針

指針和管理在復(fù)雜項(xiàng)目中十分困難冗恨,使用智能指針是不二選擇

26:使用weak_ptr來(lái)處理循環(huán)引用
27:明確對(duì)象或資源的生存周期

明確對(duì)象的生存周期通常代表著良好的設(shè)計(jì)

28:合理的使用縮進(jìn),空格

最重要的是保持風(fēng)格的統(tǒng)一味赃,自動(dòng)生成的代碼可能會(huì)打破這種統(tǒng)一掀抹,應(yīng)該靈活設(shè)計(jì)規(guī)則

29:合理使用typedef縮減類型的長(zhǎng)度,合理使用auto

使用stl時(shí)經(jīng)常會(huì)導(dǎo)致過(guò)長(zhǎng)的類型洁桌,合理使用auto可以有效減少代碼長(zhǎng)度

命名規(guī)則

由于是在VC環(huán)境下開發(fā)渴丸,沿用微軟的命名駝峰命名法

選擇哪種命名方式實(shí)際上不是很重要,最重要的是保持統(tǒng)一

  • 代碼文件: DeviceMgr.h, DeviceMgr.cpp
  • 解決方案目錄: NetLibrary
  • 工程篩選器: DataModel
  • 類:CDeviceMgr
  • 結(jié)構(gòu)體: DeviceInfo
  • 變量: listDevice
  • 類成員: m_deviceName
  • 函數(shù): GetName; GetDeviceName;
  • 代表bool含義的變量: 都以b開頭另凌,如:bOk, bSafe
  • 代表整數(shù)含義的變量: i表示符號(hào)整數(shù)谱轨,n表示無(wú)符號(hào)整數(shù)
  • 避免無(wú)意義的變量名和縮寫: 如 x,dn(deviceName)等

注釋規(guī)則

  • 文件注釋:注明文件作者吠谢,聯(lián)系方式土童,文件代碼作用,重大修改記錄等
  • 類注釋:說(shuō)明類的作用工坊,使用限制等等
  • 函數(shù)注釋: 盡量依靠意義明確的函數(shù)命名而不是依靠注釋献汗,說(shuō)明函數(shù)的使用限制,對(duì)于意義不明確的參數(shù)加以說(shuō)明
  • 變量注釋:盡量依靠意義明確的變量命名而不是依靠注釋,特殊情況王污。
  • 實(shí)現(xiàn)注釋: 對(duì)于使用了非常規(guī)技巧罢吃,或復(fù)雜算法,或很復(fù)雜的業(yè)務(wù)邏輯部分要加入注釋說(shuō)明

原則: 注釋應(yīng)風(fēng)格統(tǒng)一昭齐,簡(jiǎn)短而意義明確尿招,最終目的是有效幫助其它人閱讀和理解代碼的目的

日志

日志的打印十分重要,是產(chǎn)品發(fā)生問(wèn)題時(shí)重要的參考依據(jù)

  • 日志的打印要盡量詳盡,合理劃分日志等級(jí)就谜,一般為Fatal, ERROR, WARNING, DEBUG, INFO
  • 統(tǒng)一使用unicode(utf-16)編碼來(lái)輸出日志
  • 提供異步打印日志的接口
  • 提供定期清理日志的機(jī)制
  • 在發(fā)布版中將日志等級(jí)設(shè)置為ERROR或更高怪蔑,提供配置文件供調(diào)整日志等級(jí)

一些其它規(guī)則

  • 避免大而全的類(代碼控制在1000行以內(nèi))
  • 避免過(guò)長(zhǎng)的函數(shù)(代碼控制在200行以內(nèi))
  • 避免深層的嵌套(不要超過(guò)3層)
  • 使用do-while-break技巧來(lái)避免重復(fù)寫釋放資源的代碼
  • 盡量使用RALL技巧來(lái)釋放資源
  • 當(dāng)函數(shù)或代碼廢棄時(shí),應(yīng)與標(biāo)注丧荐,最好將其注釋掉并定期清理

線程和鎖

復(fù)雜的項(xiàng)目肯定會(huì)涉及到多線程開發(fā)缆瓣,而開發(fā)多線程程序是十分困難的。據(jù)我們統(tǒng)計(jì)虹统,項(xiàng)目組產(chǎn)品有70%左右的崩潰和bug和線程有關(guān)弓坞。

將線程模塊獨(dú)立出來(lái),交給項(xiàng)目最有經(jīng)驗(yàn)的開發(fā)人員管理和維護(hù)车荔,對(duì)外暴露抽象接口昼丑,屏蔽線程的概念。
強(qiáng)制使用RALL技術(shù)來(lái)使用鎖

未盡
本文并沒(méi)有涉及到C++規(guī)范的所有方面夸赫,歡迎討論和補(bǔ)充

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市咖城,隨后出現(xiàn)的幾起案子茬腿,更是在濱河造成了極大的恐慌,老刑警劉巖宜雀,帶你破解...
    沈念sama閱讀 219,039評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件切平,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡辐董,警方通過(guò)查閱死者的電腦和手機(jī)悴品,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)简烘,“玉大人苔严,你說(shuō)我怎么就攤上這事」屡欤” “怎么了届氢?”我有些...
    開封第一講書人閱讀 165,417評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)覆旭。 經(jīng)常有香客問(wèn)我退子,道長(zhǎng),這世上最難降的妖魔是什么型将? 我笑而不...
    開封第一講書人閱讀 58,868評(píng)論 1 295
  • 正文 為了忘掉前任寂祥,我火速辦了婚禮,結(jié)果婚禮上七兜,老公的妹妹穿的比我還像新娘丸凭。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,892評(píng)論 6 392
  • 文/花漫 我一把揭開白布贮乳。 她就那樣靜靜地躺著忧换,像睡著了一般。 火紅的嫁衣襯著肌膚如雪向拆。 梳的紋絲不亂的頭發(fā)上亚茬,一...
    開封第一講書人閱讀 51,692評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音浓恳,去河邊找鬼刹缝。 笑死,一個(gè)胖子當(dāng)著我的面吹牛颈将,可吹牛的內(nèi)容都是我干的梢夯。 我是一名探鬼主播,決...
    沈念sama閱讀 40,416評(píng)論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼晴圾,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼颂砸!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起死姚,我...
    開封第一講書人閱讀 39,326評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤人乓,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后都毒,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體色罚,經(jīng)...
    沈念sama閱讀 45,782評(píng)論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,957評(píng)論 3 337
  • 正文 我和宋清朗相戀三年账劲,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了戳护。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,102評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡瀑焦,死狀恐怖腌且,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情榛瓮,我是刑警寧澤切蟋,帶...
    沈念sama閱讀 35,790評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站榆芦,受9級(jí)特大地震影響柄粹,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜匆绣,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,442評(píng)論 3 331
  • 文/蒙蒙 一驻右、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧崎淳,春花似錦堪夭、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,996評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)恨豁。三九已至,卻和暖如春爬迟,著一層夾襖步出監(jiān)牢的瞬間橘蜜,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,113評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工付呕, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留计福,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,332評(píng)論 3 373
  • 正文 我出身青樓徽职,卻偏偏與公主長(zhǎng)得像象颖,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子姆钉,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,044評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,167評(píng)論 25 707
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理说订,服務(wù)發(fā)現(xiàn),斷路器潮瓶,智...
    卡卡羅2017閱讀 134,661評(píng)論 18 139
  • After our more-than-10-hour flight, we successfully lande...
    doooodles閱讀 261評(píng)論 4 1
  • 老生常談的一個(gè)話題克蚂,一個(gè)想當(dāng)年的丑聞,給青島抹黑的一個(gè)片段筋讨。 但是,既然出了這樣的負(fù)面消息摸恍,雖然時(shí)間過(guò)去那么久了悉罕,...
    煩人的昵稱閱讀 243評(píng)論 0 0
  • 鄙人姓瀟,名柒泩立镶,[化]字嘛……很不巧我也不知道壁袄,自幼習(xí)武,琴棋書畫媚媒,吹啦彈唱嗜逻,樣樣精通……停停停!不扯了不扯了缭召,...
    畫涼V泩閱讀 231評(píng)論 1 0