使用array(QT下用QVarLengthArray)代替和vector代替原生數組,除非與外部庫交互,不然不要直接操做內存(即暴露data的接口)程序員
關於array和vector初始化麻煩的問題,在VS2010下使用boost::assign庫,在VS2015下則使用list initial的語法算法
使用array和vector代替原生數組之後,能夠很好找到越界的地方數據庫
儘可能不要直接操做內存, 若是須要使用內存和字符串操做,儘可能使用memset_s, memcpy_s,儘可能使用_s結尾的函數json
若是須要初始化數組,使用int a[COUNT] = {0}這種語法(但實際上儘可能不要直接使用原生數組)網絡
在進行memory操做的時候,須要使用is_pod驗證下變量類型是否pod類型數據結構
使用STL的算法代替手寫的算法,日常用到的算法STL裏面或者QT的算法模塊裏面都有多線程
構造函數必定要初始化C原生類型的數據成員函數
使用C++風格的轉換,不要用C語言方式的轉換
dynamic_cast,當繼承樹不同的時候,編譯器將會報錯,或者轉換失敗,原生的C語言編譯正確而且轉換正確
static_cast,會有轉換類型檢查,好比子類往父類強轉,編譯期檢查
使用QVariant代替void*
當進行強轉錯誤的時候,QVariant能直接返回錯誤的數值
使用強枚舉
便於查看代碼
若是傳入錯誤,能夠直接讓編譯器報錯
編寫測試,系統檢測架構圖,而後 將測試用例自動化
分離數據和界面
經常使用的宏定義,放在Global裏面,相似於qt_global文件
IOCEAN裏面常常會有重複的宏定義,好比PI,好比無效的HDG,須要防止這種狀況
多用const
const的類成員函數,告訴使用者這個函數將不會對類成員進行改變,在寫代碼若是有改變,也能直接報錯
const的參數
const的引用參數
在計算出一些臨時的參數後,若是肯定這個參數不會再改變了,也建議用const
使用Q_ASSERT, assert, static_assert斷言處理邏輯上不可能出現的狀況
若是已經使用Q_ASSERT,表示這種狀況下不須要測試
在發送網絡的數據的時候,有時候發送的是純二進制數據,可是後續用戶可能會在這個數據加入非POD數據,可使用static_assert( std::is_pod<>::value) 來確保這個結構體是純二進制數據
字符串和數據結構庫統一使用QT的庫,好比QLIST,QVector,而非std::list,std::vector
爲了防止混用
與QT庫比較好結合
使用scoped_pointer和shared_pointer來代替原始指針
專一業務編寫,而非內存管理以及排錯
便於調試,若是是局部變量的指針,在release會直接被優化成地址,沒法顯示信息,若是是shared_pointer或者scoped_pointer則不會
全部建立的線程,都要設置名稱,方便查詢線程的用處
資源應該遵循誰申請誰釋放的原則,不該該把一個資源胡亂傳遞(將會致使最後資源不知道誰釋放誰持有)
CPP裏面的模塊變量使用static const而不是隻有const聲明
使用static const代替宏定義
記錄log,log不只僅是開發的時候調試使用,更是在用戶機子上分析錯誤的重要工具,如今咱們大部分的log都是維持在debug級別,應該要多編寫warning和error級別的log
因爲不少狀況下,一些錯誤的狀況沒法復現,也沒法分析,特別在部署到用戶機子上之後,很難到現場排查
一開始不必定要記錄log,根據本身的經驗判斷是否須要log,可是隨着開發進度的增長,會出現一些莫名其妙的錯誤,好比網絡不穩定,內存不穩定致使問題,排查完問題後,在發生問題的根源記錄下log
有一個問題,常常會掉線,由於網絡有時候波動會比較大,寫數據庫會很慢,這個時候若是新客戶端連上去後會發送全部的數據,將會致使心跳包處理不及時,客戶端會主動斷開,排查完緣由後,在初始化發送數據的地方編寫一段代碼,當初始化超過必定的時間後,將會記錄一個warning,下次發生這種狀況,直接經過log來排查分析
有時候一些模塊由於須要排隊處理數據,可是數據處理不即時,致使數據一直存儲在buffer裏面,可是按照正常狀況下,不該該發生這種狀況。排查完問題之後,應該在插入buffer的地方寫一個判斷代碼,當buffer大於多少後,給出一個warning
底層數據管理類不要直接暴露內部的狀況,而且將對底層數據操做的算法提取出來寫在管理類裏面,而不是你們都寫一個相同的算法
在代碼重構階段,一旦底層數據直接暴露,那麼將會很難修改
一旦代碼有相關聯的模塊,這種方式比較好處理,好比刪除元素,須要把相關聯的數據都刪除掉,若是沒有把deleteTarget封裝成一個接口,那麼須要查找全部相關聯的代碼,把這個業務的代碼再寫一遍
防止大部分人寫了相同的代碼
全部數據只有一份,包括內存裏面的數據和網絡消息,如今一個數據結構常常定義了2-3份數據,包括內存裏面的,序列化成網絡消息的
組合,繼承與接口設計
繼承要保證是一個is-a的類型,即保證一樣的邏輯操做能夠用在同一個接口上面,而不須要進行大量的轉換,若是邏輯操做出現大量的類型轉換,考慮是否繼承出現了問題
信號
將業務組合成一個函數,單獨的功能寫成一個單獨的模塊,而後在一個函數裏面將這些業務組合起來
若是有大量相同的邏輯代碼,考慮是否能夠提取成一個函數或者模板, 特別是當一個邏輯不會增長依賴的時候
若是使用了大量的dynamic_cast,而且有相同邏輯的代碼,考慮是否能夠將這個行爲抽象成一個接口
通用的庫弄成一個lib,好比SQL之類的庫
非通用的庫,可是一些項目裏面要用到的,新建一個解決方案,解決方案裏面有一個共用的庫
- 語義明確的多線程
SQL模塊 select(tablename).where("i < 7").and("j > 8").or("x < 2")
使用std::function代理SIGNAL和SLOT的綁定
將不須要製做成索引的數據使用json保存,而不是另外建立一個表而後關聯過去
儘可能使用designer進行佈局
C++11
RAII
Move語義