C++编程好习惯
本文來自于朋友LJT的日常編程心得。
1.不要在構造函數(shù)中做初始化操作
要求類(尤其是對外接口類)提供Init()函數(shù),在該函數(shù)中進行相關初始化操作,初始化失敗能夠返回錯誤碼。
可以規(guī)避問題:
?構造函數(shù)中難以返回錯誤碼,外部調用者無從判斷初始化結果。
?當該類作為全局變量使用時,構造函數(shù)調用發(fā)生在main()函數(shù)執(zhí)行之前,出現(xiàn)問題難以追蹤。
2.所有函數(shù)返回值都要判斷
可以規(guī)避問題:
?及時發(fā)現(xiàn)錯誤環(huán)節(jié),終止處理流程,避免后續(xù)發(fā)生難以預料的錯誤。
3.關于函數(shù)返回值:
?除了邏輯判斷函數(shù)外,函數(shù)返回值都為整型,且該返回值只能用來表示函數(shù)執(zhí)行情況(是否正確執(zhí)行及錯誤碼)。禁止采用bool類型作為返回值來表示函數(shù)執(zhí)行情況。
?避免void作為返回類型
?返回值不能用來傳遞結果,結果數(shù)據可以采用引用類型的出參來實現(xiàn)。
?返回值為整數(shù)時,其代表的含義統(tǒng)一規(guī)范為:小于0時表示執(zhí)行錯誤;等于0時表示執(zhí)行正確。
4.函數(shù)調用與錯誤日志
?任何函數(shù)調用失敗,必須記錄日志。
?避免無效的日志:日志中需要明確記錄錯誤碼(返回值)。除此之外,日志中還需要記錄盡量多的上下文信息,包括全部的入參信息,具有相關性的成員變量信息、全局變量信息等。
5.盡量不使用全局變量。考慮采用成員變量或者main()中的局部變量代替。
如果采用全局變量,需要給出合適的解釋。
可以規(guī)避問題:
?各種奇葩問題
6.全局變量注意事項(如果一定要使用)
?如果只在一個CPP文件中使用,那么請使用靜態(tài)(static)全局變量。例如static int a = 0;
?如果需要跨CPP使用,那么請使用較長且有區(qū)分度的名字來命名全局變量。例如。int _g_model_section_object;(解決linux上全局符號表識別錯誤問題)
?確定該全局變量類的構造函數(shù)中沒有進行復雜的初始化工作、是否依賴其他類。
?清楚:c++標準沒有規(guī)定不同編譯單元(cpp文件)中的全局對象的構造順序,只規(guī)定了同一編譯單元中的全局對象按照其定義的順序構造并倒序析構。
?清楚:全局變量初始化發(fā)生在main函數(shù)執(zhí)行前,且沒有辦法捕獲到全局對象初始化拋出的異常。
7.使用數(shù)組前要先判空。
未判空的情況下,使用下標0或者front()或者back()函數(shù)訪問數(shù)組元素都是危險的。
8.函數(shù)入參檢查與出參復歸
?防御性編程:函數(shù)開始位置應對所有入參合法性、有效性進行檢測;
?函數(shù)開始位置應該對所有出參進行清理和復歸工作;
9.字符串拷貝函數(shù)
字符串相關操作導致了太多問題。注意解決長度越界問題。
10.結構體與構造函數(shù)
?結構體中如果使用了char[]數(shù)組,必須在構造函數(shù)中給char[]數(shù)組賦初值。
例如:
?慎用memset給結構體初始化,因為結構中可能有非連續(xù)變量類型,如string等。
錯誤示例:
11.函數(shù)入參
?復雜對象(如vector)應采用引用方式作為入參,而不是值傳遞。
?對于“引用入參”應該采用const修飾符。尤其注意字符串入參應采用const char 類型,而不要采用char 。
12.”%s”與字符串
注意printf等函數(shù)中”%s”與字符串的對應關系,規(guī)避輸出崩潰問題。代碼review時,應著重檢查該類問題。
13.使用stdint.h定義的變量類型
建議采用stdint.h中定義的數(shù)據類型如int32_t、int64_t、uint32_t、uint64_t等,避免不同平臺數(shù)據長度問題。
14.命名規(guī)則
源碼文件名、動態(tài)庫名、執(zhí)行程序名采用小寫字母+下劃線的組合方式。規(guī)避操作系統(tǒng)對大小寫字母敏感導致的各類問題。
15.減少重復代碼,優(yōu)化結構設計
敗絮其中,難以金玉在外。要努力避免流水賬代碼、機械地拷貝、粘貼、無設計的堆砌。相似代碼、相似功能盡量抽取出來,封裝為一個內部公共函數(shù)。
16.動態(tài)庫中的結構體要定義在命名空間中
動態(tài)庫中所定義的結構體,要定義在專有的命名空間中。規(guī)避問題:避免動態(tài)庫與可執(zhí)行程序之間結構體重名導致的各種問題。
17.switch-case語句中必須要有default語句,且default語句中應打印相關日志信息。
18.多線程
?非線程安全的C函數(shù)。如struct tm *localtime(const time_t *timep);還有strtok、asctime、ctime、gmtime等等,使用時需要特別注意。
?多線程共享的資源,使用前要先上線程鎖。STL模板庫是非線程安全的,例如多線程共享同一個vector,那么有關vector的任何操作前都需要使用鎖保護,即使調用的僅僅是size()函數(shù)。
?關于線程的退出。不要試圖從外部強制殺掉某個線程,這樣做存在極大的內存泄漏風險。
19.配置文件采用INI格式
除非INI格式不能滿足配置要求,否則應一律采用INI格式。
20.函數(shù)提前結束,做好資源釋放工作
若在某個程序分支中提前退出函數(shù),請不要忘記釋放內存、數(shù)據庫句柄、文件句柄等資源,否則會導致內存泄漏,資源耗盡。
舉例:
21.消缺與維護
?克服僥幸心理,問題只要出現(xiàn)一次就肯定會出現(xiàn)第二次第三次….;
?不要放過小問題,小問題可能遷出大問題;
?不應通過“試”來解決問題,應尋找問題的根本原因;
?修復BUG需謹慎,全盤考慮,避免引入新BUG。
總結
- 上一篇: CS231n 学习笔记(4)——神经网络
- 下一篇: u盘没有显示文件怎么办 解决U盘文件不显