如何編寫代碼++的C?
概述
本文僅供參考。
如果您正在編輯代碼奶镶,那么編寫有章法的代碼是很有意義的。
您的書寫風(fēng)格是需要與現(xiàn)有代碼保持一致的。
更簡單的理解代碼(更方便)需要代碼具有統(tǒng)一性笔横。而且,統(tǒng)一的代碼使搜索更加容易咐吼。
本文之中諸多規(guī)則非也合理吹缔,往往是依例而為。
格式化
您寫的代碼將被自動(dòng)執(zhí)行clang-format锯茄。
縮進(jìn) - 4個(gè)空格厢塘。配置開發(fā)環(huán)境,以便該選項(xiàng)卡添加四個(gè)空格肌幽。
新的一行上書寫大括號(hào)晚碾。(括號(hào)結(jié)尾亦如此)
inline void readBoolText (bool &x ,ReadBuffer &buf ){?
????char tmp = '0' ;
? ? readChar (tmp 喂急,buf );?
????x = tmp 格嘁!= '0' ;?
}
但是,如果函數(shù)的全部足夠短(一個(gè)語句) - 如果需要廊移,它可以完全放在一行上糕簿。在這種情況下探入,在花括號(hào)的周圍放置空白(除了行尾的空格)。
inline size_t mask ()? ? ? ? ? ? ? ? ? ? ? ? ? ? const {? ?return buf_size ()- 1 ; }?
inline size_t place (HashValue x )? ? ? ?const {? ? return x &mask ();? ?}
對(duì)于功能來說懂诗,圓括號(hào)不會(huì)有空格蜂嗽。
void reinsert (const Value &x )
memcpy (&buf [ place_value ],&x 殃恒,sizeof (x ));
當(dāng)使用if植旧,for,while离唐,...(而不是函數(shù)調(diào)用)時(shí)病附,在左括號(hào)之前放置一個(gè)空格。
for (為size_t 我= 0 ; 我< 行; 我+ = 存儲(chǔ)侯繁。index_granularity )
圍繞二元運(yùn)算符(+胖喳, - ,*贮竟,/丽焊,%,...)以及三元運(yùn)算符咕别?:空間被放置技健。
UINT16 年= (小號(hào)[ 0 ] - '0' )* 1000 + (小號(hào)[ 1 ] - '0' )* 100 + (小號(hào)[ 2 ] - '0' )* 10 + (小號(hào)[ 3 ] - “0 ' ); UInt8 月= (s [ 5 ] - '0' )* 10 + (s [ 6 ] - '0' ); UInt8 day = (s [ 8 ] - '0' )* 10 + (s [ 9 ] - '0' );
如果您張貼一行,則該語句將寫入一個(gè)新行惰拱,并且縮進(jìn)之前遞增雌贱。
中頻(elapsed_ns )消息<< “(” << rows_read_on_server * 10億/ elapsed_ns << “行/秒,偿短⌒拦拢” << bytes_read_on_server * 1000.0 / elapsed_ns << “MB立即下載/秒)∥舳海” ;
在行內(nèi)降传,如果需要,可以用空格對(duì)齊勾怒。
dst 婆排。ClickLogID = 點(diǎn)擊。LogID ; dst 笔链。ClickEventID = 點(diǎn)擊段只。EventID ; dst 。ClickGoodEvent = 點(diǎn)擊鉴扫。GoodEvent ;
在Carrier周圍? .赞枕,->沒有空格。
如有必要,可以將Carrier轉(zhuǎn)移到新行鹦赎。在這種情況下谍椅,空格在它之前增加。
一元運(yùn)算符(古话,...)不能與空間分隔。--,?++,?*,?&
在逗號(hào)之后放置一個(gè)空格锁施,之前 - 不存在陪踩。for語句中的分號(hào)類似。
操作員[]不能被空格分開悉抵。
在該表達(dá)式中肩狂,間,和前面有一個(gè)空格;?之后和之前-未分配姥饰。template?<...>template<<>
template < typename TKey 傻谁,typename TValue > struct AggregatedStatElement {}
在類和結(jié)構(gòu)中,公共的列粪,私有的审磁,被保護(hù)的被寫在與類/結(jié)構(gòu)相同的層次上,而其他所有的內(nèi)部都是更深的岂座。
template < typename T > class MultiVersion {?
public :///使用對(duì)象的版本态蒂。
????shared_ptr 管理版本的生命周期。
????using Version = std :: shared_ptr < const T > ;
?????...?
}
如果整個(gè)文件上有一個(gè)命名空間费什,除此之外沒有任何必要钾恢,那么名稱空間內(nèi)的縮進(jìn)就不需要了。
如果表達(dá)式if鸳址,for瘩蚪,while ...的塊由一個(gè)語句組成,則花括號(hào)不需要寫入稿黍。相反疹瘦,把語句放在一個(gè)單獨(dú)的行上。這個(gè)語句也可以嵌套闻察,如果for拱礁,while ...但是如果inner語句包含大括號(hào)或者其他的,那么外部的塊應(yīng)該被寫在大括號(hào)中辕漂。
///完成寫入呢灶。for (auto &stream :streams )流。第二個(gè)- > finalize ();
行尾應(yīng)該沒有空格钉嘹。
以UTF-8編碼的源代碼鸯乃。
在字符串文字中,您可以使用非ASCII。
<< “” << (計(jì)時(shí)器缨睡。消逝()/ chunks_stats 鸟悴。點(diǎn)擊數(shù))<< “微秒/命中”。;
不要在一行中寫入多個(gè)表達(dá)式奖年。
在函數(shù)內(nèi)部细诸,對(duì)代碼段進(jìn)行分組,使用不超過一個(gè)空行分隔它們陋守。
功能震贵,類別等至少由一個(gè),至多兩個(gè)空行相互隔開水评。
const(引用該值)被寫入類型名稱猩系。
// 正確的const char * pos const std :: string &s // 不正確的char const * pos
當(dāng)你聲明一個(gè)指針或引用時(shí),*和&字符被兩邊的空格分開中燥。
// 正確的const char * pos // 不正確的const char * pos const char * pos
當(dāng)使用模板類型時(shí)寇甸,寫using(除了最簡單的情況)。
也就是說疗涉,模板參數(shù)僅在using代碼中指定拿霉,然后在代碼中不重復(fù)。
using?可以在本地聲明博敬,例如在一個(gè)函數(shù)內(nèi)友浸。
// 正確使用FileStreams = std :: map < std :: string ,std :: shared_ptr < Stream >> ; FileStreams 流; // 不正確的std :: map < std :: string 偏窝,std :: shared_ptr < Stream > 流;
你不能在同一個(gè)聲明中聲明多個(gè)不同類型的變量收恢。
// true int x ,* y ;
C風(fēng)格演員沒有使用祭往。
//不正確的std :: cerr << (int )c << ; std :: endl ; //正確的std :: cerr << static_cast < int > (c )<< std :: endl ;
在課程和結(jié)構(gòu)中伦意,分別在每個(gè)范圍內(nèi)分別分組和分組。
對(duì)于不是很大的類/結(jié)構(gòu)硼补,您不能將方法聲明與實(shí)現(xiàn)分開驮肉。
類似于任何類/結(jié)構(gòu)中的小方法。
對(duì)于模板類/結(jié)構(gòu)已骇,最好不要將方法聲明與實(shí)現(xiàn)分開(否則它們必須在同一個(gè)翻譯單元中定義)离钝。
代碼寬度不能超過80個(gè)字符。有可能在140褪储。
如果不需要postfix卵渴,請(qǐng)始終使用前綴遞增/遞減。
對(duì)于(姓名:: 為const_iterator IT = COLUMN_NAMES 鲤竹。在開始(); IT 浪读!= COLUMN_NAMES 。結(jié)束(); ++ IT )
評(píng)論(注釋)
有必要在所有需要解釋的地方寫評(píng)論。
這非常重要碘橘。我們不應(yīng)當(dāng)為他人創(chuàng)造閱讀代碼的多余工作互订,而應(yīng)當(dāng)簡便的介紹代碼的內(nèi)容。
/ **一部分內(nèi)存痘拆,可以使用仰禽。? * 例如,如果internal_buffer為1MB 错负,并且有唯一的圖10中坟瓢,加載到緩沖“從文件中的字節(jié)進(jìn)行讀取,? *當(dāng)時(shí)working_buffer將具有僅為10字節(jié)大小床? *(working_buffer.end()點(diǎn)位置將可用的那些10個(gè)字節(jié)之后的閱讀)犹撒。? * /
注釋可以盡可能詳細(xì)。
注釋被寫入適當(dāng)?shù)拇a粒褒。在極少數(shù)情況下 - 可以放置于同一行之后识颊。
/** Parses and executes the query.*/
void executeQuery( ReadBuffer & istr,? /// Where to read the query from (and data for INSERT, if? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?applicable)WriteBuffer & ostr,/// Where to write the result
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?Context? & context,/// DB, tables, data types, engines, functions, aggregate? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? functions...BlockInputStreamPtr & query_plan,///executedQueryProcessingStage::Enum
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?stage=QueryProcessingStage::Complete/// Up to which stage process the SELECT query)
注釋只能用英文書寫。
編寫一個(gè)庫時(shí)奕坟,請(qǐng)?jiān)谧钪匾念^文件中發(fā)布一個(gè)關(guān)于它是什么的詳細(xì)注釋祥款。
你不能寫評(píng)論,不提供額外的信息月杉。特別是刃跛,你不能寫這樣的空的評(píng)論:
/ * *過程如何名稱:*原程序名稱:*作者:*創(chuàng)造條件的日期:*修改的日期:*修改作者:*原始文件名:*用途:*的意圖:*的名稱:*在類中使用:*常量:*局部變量:*參數(shù):*創(chuàng)建日期:*目的:* /
(實(shí)施例從資源采取http://home.tamk.fi/~jaalto/course/coding-style/doc/unmaintainable-code/
您不能在每個(gè)文件的開頭寫入垃圾評(píng)論(作者,創(chuàng)建日期...)苛萎。
單行注釋以三個(gè)斜杠開始:///多行與/**桨昙。這樣的評(píng)論被認(rèn)為是“記錄”。
注意:這些注釋可用于使用Doxygen生成文檔腌歉。但是蛙酪,實(shí)際上,Doxygen并沒有被使用翘盖,因?yàn)槭褂肐DE功能導(dǎo)航代碼要方便得多桂塞。
在多行注釋的開始和結(jié)尾,不應(yīng)該有空行(除了多行注釋關(guān)閉的行外)馍驯。
對(duì)于注釋的代碼塊阁危,通常不使用“記錄”注釋。
在提交之前刪除注釋的代碼塊汰瘫。
不要在評(píng)論或代碼中寫粗話狂打。
不要用大寫字母寫。不要使用不必要的標(biāo)點(diǎn)符號(hào)吟吝。
///WHAT A FALIURE
不要在評(píng)論中撰寫分隔線菱父。
/// *********************************************** *******
在評(píng)注中寫下對(duì)話是沒有必要的(最好口頭說)。
///你為什么要做這個(gè)東西?
不要在塊的末尾寫下關(guān)于這個(gè)塊的評(píng)論浙宜。
/// for
名稱
變量和類成員的名稱是帶有下劃線的小寫字母官辽。
size_t max_block_size ;
函數(shù)(方法)的名字是用小寫字母camelCase。
std :: string getName ()const override { return “Memory” ; }
類(結(jié)構(gòu))的名稱是大寫字母的CamelCase粟瞬。不使用接口以外的前綴同仆。
類StorageMemory :公共IStorage
使用的名稱以及類,或者您可以在最后添加_t裙品。
類型名稱 - 模板參數(shù):在簡單情況下 - T;?T俗批,U;?T1,T2市怎。
在更復(fù)雜的情況下 - 無論是類名岁忘,還是可以將字母T添加到開頭。
template < typename TKey 区匠,typename TValue > struct AggregatedStatElement
常量的名稱 - 模板的參數(shù):或者變量的名稱干像,或者簡單情況下的N。
template < bool without_www > struct ExtractDomain
對(duì)于抽象類(接口)驰弄,可以將字母I添加到名稱的開頭麻汰。
類IBlockInputStream
如果變量在本地使用,那么可以使用簡稱戚篙。
在其他情況下 - 使用描述含義的相當(dāng)詳細(xì)的名稱五鲫。
bool info_successfully_loaded = false ;
定義-s - 帶下劃線的ALL_CAPS。全局常量 - 也是岔擂。
#define MAX_SRC_TABLE_NAMES_TO_STORE 1000
具有代碼的文件的名稱根據(jù)其中的內(nèi)容根據(jù)樣式命名位喂。
如果在文件中有一個(gè)類 - 在CamelCase中將該文件命名為一個(gè)類。
如果文件中有一個(gè)函數(shù) - 將該文件命名為函數(shù) - 在camelCase中智亮。
如果名稱包含縮寫忆某,則:
對(duì)于變量名,所有的縮寫都是用小寫字母mysql_connection(不mySQL_connection)阔蛉。
對(duì)于類和函數(shù)的名字弃舒,大的字母保留在縮寫MySQLConnection(not?MySqlConnection)中。
應(yīng)立即使用用于初始化類的相應(yīng)成員的構(gòu)造函數(shù)的參數(shù)以及類的成員状原,并在末尾添加下劃線聋呢。
FileQueueProcessor (const的在std :: :字符串和path_ ,常量在std :: :字符串和prefix_ 颠区,在std :: shared_ptr的< 文件處理器> handler_ ):路徑(path_ )削锰,前綴(prefix_ ),處理器(handler_ )毕莱,日志(&記錄器:: 的get (“FileQueueProcessor” )){ }
您也可以像構(gòu)造函數(shù)的成員一樣調(diào)用構(gòu)造函數(shù)的參數(shù)(不要添加下劃線)器贩,但只有在構(gòu)造函數(shù)的主體中不使用此參數(shù)時(shí)才可以颅夺。
命名局部變量和類成員沒有區(qū)別(不需要前綴)。
定時(shí)器(不是m_timer )
enum-e中的常量 - 使用大寫字母的CamelCase蛹稍。ALL_CAPS也是可以接受的吧黄。如果枚舉不在本地,則使用枚舉類唆姐。
枚舉類CompressionMethod { QuickLZ = 0 拗慨,LZ4 = 1 ,};
所有的名字都是英文的奉芦。俄語字符赵抢、漢語字符、日語字符等不得使用声功。
不要使用Stroka?
名稱中的縮寫(來自不同單詞的幾個(gè)字母)只有在被普遍接受的情況下才可以使用(如果縮短可以在英文維基百科中進(jìn)行解碼或進(jìn)行搜索查詢): AST烦却,SQL。
No NVDH
只有在廣泛使用這種縮減的情況下先巴,才能使用縮略語的縮略語短绸。
但是,如果縮寫的代碼全稱就在注釋附近出現(xiàn)過筹裕,也可以使用縮寫。
C ++源文件名只能有.cpp擴(kuò)展名窄驹。頭文件 - 只有.h朝卒。
如何編寫代碼
內(nèi)存管理。
手動(dòng)刪除內(nèi)存(刪除)只能在庫代碼中使用乐埠。
而在庫代碼中抗斤,刪除操作符只能在析構(gòu)函數(shù)中使用。
在應(yīng)用程序代碼中丈咐,應(yīng)該完成內(nèi)存被擁有它的某個(gè)對(duì)象釋放瑞眼。
例子:
將對(duì)象放在堆棧上,或者使其成為另一個(gè)類的成員是最簡單的棵逊。
對(duì)于大量的小物件伤疙,使用容器。
要自動(dòng)釋放堆中分配的少量對(duì)象辆影,請(qǐng)使用shared_ptr / unique_ptr徒像。
資源管理。
使用RAII并參見上面的段落蛙讥。
錯(cuò)誤處理锯蛀。
使用例外。在大多數(shù)情況下次慢,您只需要拋出異常旁涤,而不需要捕捉(因?yàn)镽AII)翔曲。
在離線數(shù)據(jù)處理程序中,通常你不能捕捉異常劈愚。
在處理自定義請(qǐng)求的服務(wù)器中瞳遍,通常在連接處理程序的頂部捕獲異常就足夠了。
在線程函數(shù)中造虎,你應(yīng)該捕獲并記住所有異常傅蹂,在加入之后將它們拋入主線程中。
///如果還沒有計(jì)算算凿,如果(份蝴!Started ){ calculate (); 開始= 真; } else ///如果計(jì)算已經(jīng)在運(yùn)行,請(qǐng)等待池的結(jié)果氓轰。wait (); 如果(例外)異常- > rethrow ();
不要“不分青紅皂白地”吞食“例外婚夫。在任何情況下,都不要將所有例外不加區(qū)分地轉(zhuǎn)換成日志中的消息署鸡。
不要案糙。catch?(...)?{}
如果您需要忽略一些例外情況,那么只需要忽略特定的例外情況靴庆,其余部分則會(huì)退回时捌。
捕捉(const的DB :: 異常&? ){ 如果(? 。代碼()== ErrorCode的:: UNKNOWN_AGGREGATE_FUNCTION )返回nullptr ; 否則扔; }
當(dāng)使用使用返回碼或errno的函數(shù)時(shí)炉抒,檢查結(jié)果并拋出異常奢讨。
if (0 != close (fd ))throwFromErrno (“Can not close file” + file_name 焰薄,ErrorCodes :: CANNOT_CLOSE_FILE );
斷言不被使用拿诸。
異常類型。
在應(yīng)用程序代碼中塞茅,您不需要使用復(fù)雜的異常層次結(jié)構(gòu)亩码。希望系統(tǒng)管理員能夠理解例外文本。
從析構(gòu)函數(shù)中出現(xiàn)的異常野瘦。不建議使用描沟,但可以接受。
使用以下選項(xiàng):
做一個(gè)函數(shù)(done()或finalize())缅刽,它可以讓你事先執(zhí)行所有的工作啊掏,在這個(gè)過程中可能會(huì)發(fā)生異常。如果這個(gè)函數(shù)被調(diào)用衰猛,那么在析構(gòu)函數(shù)中不應(yīng)該有任何異常迟蜜。
過于復(fù)雜的工作(例如通過網(wǎng)絡(luò)發(fā)送數(shù)據(jù))在析構(gòu)函數(shù)中根本無法完成,期望用戶提前調(diào)用該方法來完成工作啡省。
如果在析構(gòu)函數(shù)中發(fā)生異常娜睛,建議不要“吞食”它髓霞,而是將信息輸出到日志(如果在此處有日志記錄器)。
在簡單的程序畦戒,如果相關(guān)的異常沒有被捕獲方库,并導(dǎo)致與在日志中記錄信息的工作完成后,你可以不用擔(dān)心從析構(gòu)函數(shù)發(fā)出的異常障斋,因?yàn)檎{(diào)用的std ::終止(在默認(rèn)noexcept在C ++ 11的情況下)是處理異常的可接受的方式纵潦。
獨(dú)立的代碼塊。
在一個(gè)函數(shù)內(nèi)部垃环,可以創(chuàng)建一個(gè)單獨(dú)的代碼塊邀层,以便在其中創(chuàng)建一些局部變量,并在退出塊時(shí)調(diào)用相應(yīng)的析構(gòu)函數(shù)遂庄。
塊塊= 數(shù)據(jù)寥院。in - > read (); { std :: lock_guard < std :: mutex > lock (mutex ); 數(shù)據(jù)。ready = true ; 數(shù)據(jù)涛目。block = block ; } Ready_any 秸谢。set ();
多線程。
在離線數(shù)據(jù)處理程序中:
首先霹肝,在單個(gè)處理器內(nèi)核上實(shí)現(xiàn)或多或少的最大性能估蹄,然后您可以并行化代碼,但只在必要的時(shí)候使用沫换。
在服務(wù)器程序中:
使用線程池來處理請(qǐng)求元媚。目前,我們沒有任何需要使用用戶空間上下文切換的任務(wù)苗沧。
叉不用于并行化。
流的同步炭晒。
通常待逞,你可以單獨(dú)的流數(shù)據(jù)寫入到不同的存儲(chǔ)位置(更好 - 在不同的緩存行),并且不使用流同步(除joinAll)网严。
如果需要同步识樱,在大多數(shù)情況下,使用lock_guard下的互斥鎖就足夠了震束。
在其他情況下怜庸,使用系統(tǒng)同步原語。不要用忙等待垢村。
原子操作只能用于最簡單的情況割疾。
除非你是專家,否則你不需要自己寫一個(gè)無鎖的數(shù)據(jù)結(jié)構(gòu)嘉栓。
參考和指標(biāo)宏榕。
在大多數(shù)情況下拓诸,更喜歡鏈接。
常量麻昼。
可以使用常量引用奠支,常量指針,const_iterator抚芦,常量方法倍谜。
考慮到const是“缺省”寫入的變體,只有必要時(shí)才需要const的缺失叉抡。
對(duì)于通過值傳遞的變量尔崔,const通常是沒有意義的。
無符號(hào)卜壕。
如果需要您旁,使用無符號(hào)。
數(shù)字類型轴捎。
使用類型UInt8鹤盒,UInt16,UInt32侦副,UInt64侦锯,Int8,Int16秦驯,Int32尺碰,Int64以及size_t,ssize_t译隘,ptrdiff_t亲桥。
不要使用signed / unsigned long,long long固耘,short;?signed char题篷,unsigned char和char。
傳遞參數(shù)厅目。
復(fù)合值是通過引用傳遞的(包括std :: string)番枚。
如果該函數(shù)捕獲在堆上創(chuàng)建的對(duì)象的所有權(quán),則使參數(shù)類型為shared_ptr或unique_ptr损敷。
返回值葫笼。
在大多數(shù)情況下,只需返回值拗馒。不要寫[return std :: move(res)] {路星。Strike}。
如果在函數(shù)內(nèi)部在堆上創(chuàng)建一個(gè)對(duì)象并發(fā)出诱桂,則返回shared_ptr或unique_ptr奥额。
在少數(shù)情況下苫幢,可能需要通過函數(shù)參數(shù)返回一個(gè)值。在這種情況下垫挨,參數(shù)是一個(gè)鏈接韩肝。
使用AggregateFunctionPtr = std :: shared_ptr < IAggregateFunction > ; / **允許您通過名稱創(chuàng)建一個(gè)聚合函數(shù)。? * / class AggregateFunctionFactory { public :AggregateFunctionFactory (); AggregateFunctionPtr get (const String &name 九榔,const DataTypes &argument_types )const ;
命名空間哀峻。
對(duì)于應(yīng)用程序代碼,您不需要使用單獨(dú)的名稱空間哲泊。
對(duì)于小型圖書館 - 不需要剩蟀。
對(duì)于不是很小的圖書館 - 把所有的東西放在名字空間里
在.h文件庫中,可以使用名稱空間詳細(xì)信息來獲取應(yīng)用程序代碼不需要的實(shí)現(xiàn)細(xì)節(jié)切威。
在.cpp文件中育特,可以使用靜態(tài)或匿名命名空間來隱藏字符。
此外先朦,命名空間可以用于枚舉缰冤,以便相應(yīng)的名稱不會(huì)進(jìn)入外部名稱空間(但最好使用枚舉類)。
延遲初始化喳魏。
通常棉浸,如果您需要參數(shù)來初始化,請(qǐng)不要為了邏輯而編寫構(gòu)造函數(shù)刺彩。
如果那么你需要延遲初始化迷郑,那么你可以添加一個(gè)默認(rèn)的構(gòu)造函數(shù)(這將創(chuàng)建一個(gè)不正確的狀態(tài)的對(duì)象)〈淳螅或者嗡害,對(duì)于少數(shù)對(duì)象,可以使用shared_ptr / unique_ptr畦攘。
Loader (DB :: Connection * connection_ 就漾,const std :: string &query ,size_t max_block_size_ ); ///用于延遲初始化Loader (){}
虛擬功能念搬。
如果這個(gè)類不是為多態(tài)使用而設(shè)計(jì)的,那么你就不需要使這個(gè)函數(shù)虛擬化摆出。這也適用于析構(gòu)函數(shù)朗徊。
編碼。
UTF-8被廣泛使用偎漫。使用std::string爷恳,。未使用象踊,温亲。char?*std::wstringwchar_t
日志記錄棚壁。
查看代碼中的所有示例。
在提交之前栈虚,刪除所有無意義和調(diào)試日志袖外,以及其他類型的調(diào)試輸出。
內(nèi)部循環(huán)的每個(gè)迭代都不應(yīng)該有日志記錄魂务,即使是跟蹤級(jí)別也是如此曼验。
在任何級(jí)別的日志記錄中,日志都應(yīng)該可以讀取粘姜。
日志記錄應(yīng)該主要用在應(yīng)用程序代碼中鬓照。
日志中的信息應(yīng)該用英文書寫。
系統(tǒng)管理員可以理解日志孤紧。
不需要在日志中寫下臟話豺裆。
日志使用UTF-8編碼。偶爾号显,日志中可以使用非ASCII字符胁艰。
I / O.
在內(nèi)部循環(huán)(在程序的關(guān)鍵部分)氯夷,你不能使用iostreams(包括,絕不使用stringstream)。
而是使用DB / IO庫金砍。
日期和時(shí)間。
查看DateLUT庫挽放。
Include
頭文件僅用于捐友,包括guard-s不需要寫。#pragma?once
Using
不使用名稱空間钾菊。
使用一些具體的東西 - 這是可能的帅矗。在本地更好 - 在課堂上或功能上。
如果沒有必要煞烫,則不需要使用函數(shù)的尾隨返回類型浑此。
[auto f() ->? void;] {.strike}
你不需要像這樣聲明和初始化變量:
auto s = std :: string { “Hello” };
這是必要的:
std :: string s = “Hello” ; std :: string s { “Hello” };
對(duì)于虛擬函數(shù),在基類中寫入虛擬滞详,在繼承類中寫入覆蓋凛俱,不寫虛擬。
未使用的語言特性++的C?
虛擬繼承不使用料饥。
不使用C ++ 03的異常限定符蒲犬。
函數(shù)try塊不被使用,除了測(cè)試中的主函數(shù)岸啡。
平臺(tái)
我們編寫一個(gè)非跨平臺(tái)的代碼(針對(duì)特定的平臺(tái))原叮。
盡管其他條件相同,但是更多或更少的跨平臺(tái)或便攜代碼是優(yōu)選的。
語言 - C ++ 17奋隶。
編譯器是gcc擂送。目前(2017年12月),代碼將版本7.2唯欣。(也可以用clang 5編譯代碼)
使用標(biāo)準(zhǔn)庫(實(shí)現(xiàn)libstdc ++或libc ++)嘹吨。
操作系統(tǒng) - Linux Ubuntu,不比Precise大黍聂。
該代碼是為體系結(jié)構(gòu)x86_64的處理器編寫的躺苦。
一套指令是我們的服務(wù)器支持的最低要求。現(xiàn)在是SSE4.2产还。
編譯標(biāo)志被使用匹厘。-Wall?-Wextra?-Werror
使用帶有除了那些困難的所有庫靜態(tài)鏈接到靜態(tài)連接(見。結(jié)論LDD命令)脐区。
代碼是用程序集的發(fā)布參數(shù)開發(fā)和調(diào)試的愈诚。
工具
KDevelop是一個(gè)很好的開發(fā)環(huán)境。
對(duì)于調(diào)試牛隅,使用gdb炕柔,valgrind(memcheck),strace媒佣,-fsanitize = ...匕累,tcmalloc_minimal_debug。
性能分析使用Linux Perf默伍,valgrind(callgrind)欢嘿,strace -cf。
來源于Git也糊。
用CMake構(gòu)建炼蹦。
程序使用deb包進(jìn)行布局。
Master承諾不應(yīng)該破壞項(xiàng)目的組裝狸剃。
所收集的程序的工作能力僅保證個(gè)人審計(jì)掐隐。
盡可能經(jīng)常提交,包括非工作代碼钞馁。
要做到這一點(diǎn)虑省,使用 branch。
如果您的主代碼還沒有準(zhǔn)備好僧凰,那么在推送它之前 - 從程序集中排除它探颈,您將不得不修改它或在幾天內(nèi)刪除它。
對(duì)于不重要的更改允悦,使用branch。應(yīng)該將分支上傳到服務(wù)器。
不必要的代碼從source中刪除隙弛。
庫
使用標(biāo)準(zhǔn)的C ++庫14(允許使用 Experimental 擴(kuò)展)以及 Poco 框架架馋。
如有必要,您可以使用軟件包中操作系統(tǒng)中可用的任何已知庫全闷。
如果有一個(gè)好的現(xiàn)成的解決方案叉寂,那就使用它,即使你需要為此安裝一個(gè)庫总珠。
(但要做好準(zhǔn)備屏鳍,因?yàn)橛袝r(shí)候你必須從代碼中剔除不好的庫。)
如果軟件包中沒有庫局服,或者版本足夠舊钓瞭,或者沒有以正確的方式編譯,則可以使用未從軟件包安裝的庫淫奔。
如果庫足夠小山涡,并且沒有自己的構(gòu)建系統(tǒng),則應(yīng)將其文件包含在項(xiàng)目的contrib目錄中唆迁。
總是優(yōu)先考慮已經(jīng)在使用的library庫鸭丛。
一般
寫盡可能少的代碼。
嘗試最簡單的解決方案唐责。
如果您不知道程序?qū)?zhí)行什么操作鳞溉,以及內(nèi)部循環(huán)如何工作,則無需編寫代碼鼠哥。
在最簡單的情況下熟菲,使用 using 而不是class/struct。
如果可能的話肴盏,不要寫復(fù)制構(gòu)造函數(shù)科盛,賦值運(yùn)算符,析構(gòu)函數(shù)(除非虛擬類至少包含一個(gè)虛函數(shù))菜皂,移動(dòng)構(gòu)造函數(shù)和移動(dòng)賦值贞绵。也就是說,編譯器生成的相應(yīng)函數(shù)正常工作恍飘。你可以使用默認(rèn)榨崩。
簡化和減少代碼量是值得歡迎的。
此外
顯式的std ::用于stddef.h中的類型章母。
建議不要指定母蛛。也就是說,建議編寫size_t而不是std :: size_t - 因?yàn)樗泳?/b>乳怎。
但是彩郊,如果你想,你仍然可以分配std :: - 這個(gè)選項(xiàng)也是可以接受的。
基本的std ::用于標(biāo)準(zhǔn)C庫中的函數(shù)秫逝。
不推薦恕出。也就是說,寫入memcpy而不是std :: memcpy违帆。
原因 - 有類似的非標(biāo)準(zhǔn)功能浙巫,例如memmem。我們可以使用和偶爾使用這些功能刷后。這些函數(shù)在命名空間std中找不到的畴。
如果你在任何地方都寫std :: memcpy而不是memcpy,那么在不用std ::的情況下查看memmem將會(huì)很不方便尝胆。
但是丧裁,指定std ::也是可以接受的,如果這更像班巩。
如果標(biāo)準(zhǔn)C ++庫中有類似物渣慕,則使用C中的函數(shù)。
如果這種使用更有效抱慌,這是允許的逊桦。
例如,要復(fù)制長塊的內(nèi)存抑进,請(qǐng)使用memcpy而不是std :: copy强经。
傳遞長函數(shù)參數(shù)。
可以使用任何傳輸方式寺渗,類似于下面列出的傳輸方式:
功能(T1 x1 匿情,T2 x2 )
函數(shù)(size_t left ,size_t right 信殊,const &RangesInDataParts 范圍炬称,size_t 限制)
函數(shù)(size_t left ,size_t right 涡拘,const &RangesInDataParts 范圍玲躯,size_t 限制)
函數(shù)(size_t left ,size_t right 鳄乏,const &RangesInDataParts 范圍跷车,size_t 限制)
函數(shù)(size_t left ,size_t right 橱野,const &RangesInDataParts 范圍朽缴,size_t 限制)