- endl會在流中插入新行且清空緩沖區(qū),因此過度使用endl會影響性能;\n也會在流中插入新行但不會清空緩沖區(qū)。
- 不要在頭文件的全局作用域中使用using指令或using聲明,盡可能放在更小的作用域中。
- 慎重使用using enum聲明,以防產(chǎn)生名字沖突。
- 使用強(qiáng)類型的enum class枚舉,代替舊風(fēng)格的、類型不安全的enum枚舉。
- 在C++中,數(shù)組的第一個元素在位置0,不是位置1;最后一個元素的位置是數(shù)組長度減一。
- 原始的裸指針只在不涉及所有權(quán)時使用;其他情況應(yīng)該使用智能指針。
- 在解引用之前,指針必須是有效的;解引用一個null指針或未初始化的指針會導(dǎo)致未定義行為。
- 為了防止內(nèi)存泄漏,每次調(diào)用new/new[]都必須匹配相應(yīng)的delete/delete[]。
- 引用變量必須在創(chuàng)建時初始化。
- 引用一旦被初始化指向一個指定變量,就不可以修改它指向其他變量。
- 類的引用數(shù)據(jù)成員需要在構(gòu)造函數(shù)初始值列表中初始化。
- 從函數(shù)返回對象的推薦方法是按值返回,而不使用輸出參數(shù)。
- 不要從函數(shù)返回指向局部變量的引用,因?yàn)楫?dāng)函數(shù)結(jié)束時,在棧上自動分配的變量會被銷毀。
- 使用別名(using)勝過typedef。
- auto會忽略引用和const并產(chǎn)生復(fù)制成本。如果不想要復(fù)制,則使用auto&或const auto&。
- 使用std::string類代替C風(fēng)格的字符串。
- 返回字符串的函數(shù)應(yīng)該返回一個const string&或string而非string_view。
- 保存一個const string&或string_view作為類的數(shù)據(jù)成員要求你確保其所指向的字符串在對象的生命周期中保持存活。然而保存一個std::string更安全。
- 不要使用std::string_view保存臨時字符串。
- 當(dāng)設(shè)計(jì)接口時,不要給用戶暴露實(shí)現(xiàn)細(xì)節(jié)。
- 在現(xiàn)代C++代碼中,你應(yīng)該盡量避免使用底層的內(nèi)存操作,而使用如容器和智能指針等現(xiàn)代構(gòu)件。
- 每當(dāng)你聲明一個指針變量時,應(yīng)該立即初始化。
- 不要在C++中使用malloc()和free()。
- 在現(xiàn)代C++中,你應(yīng)該避免使用C風(fēng)格指針。你應(yīng)該在現(xiàn)代標(biāo)準(zhǔn)庫容器中保存智能指針,而不是在C風(fēng)格數(shù)組中保存原始指針。智能指針會在適當(dāng)時間自動釋放關(guān)聯(lián)內(nèi)存。
- 數(shù)組可以被自動地視作指針,但不是所有指針都是數(shù)組。
- 避免使用舊C風(fēng)格的字符串和數(shù)組,它們不提供任何保護(hù)。相反,使用現(xiàn)代的、安全的構(gòu)件,如C++ string和vector,它們會為你管理內(nèi)存。
- 不要把資源分配的結(jié)果賦予一個原始指針。無論你使用何種資源分配方法,都要立即把資源指針保存在一個智能指針中,unique_ptr或shared_ptr或其他RAII類。RAII表示Resource Acquisition Is Initialization(資源獲取即初始化)。RAII類持有特定資源的所有權(quán)并且在適當(dāng)時間處理釋放操作。
- 使用make_shared()創(chuàng)建shared_ptr。
- 在現(xiàn)代C++代碼中,僅當(dāng)不涉及所有權(quán)時才允許使用原始指針。如果涉及所有權(quán),則默認(rèn)使用unique_ptr;如果需要共享所有權(quán),則使用shared_ptr。另外使用make_unique()和make_share()創(chuàng)建這些智能指針。
- 當(dāng)在棧上用默認(rèn)構(gòu)造函數(shù)創(chuàng)建一個對象時,使用統(tǒng)一初始化語法的大括號或者省略任何括號。
- 構(gòu)造函數(shù)初始值列表以在類定義中的順序來初始化數(shù)據(jù)成員,而非以在初始值列表中的順序。
- 事實(shí)上你可以聲明賦值運(yùn)算符函數(shù)返回任意類型(包括void)。但是你應(yīng)該總是返回一個調(diào)用對象的引用。
- 當(dāng)在類中有動態(tài)分配的資源時,你應(yīng)該編寫自己的復(fù)制構(gòu)造函數(shù)和賦值運(yùn)算符函數(shù)來實(shí)現(xiàn)內(nèi)存的深度復(fù)制。
- 當(dāng)實(shí)現(xiàn)賦值運(yùn)算符函數(shù)時,使用copy-and-swap慣用法來避免代碼重復(fù)并保證強(qiáng)異常安全。
- 一個命名的rvalue引用本身是一個lvalue,因?yàn)樗忻帧?/li>
- 當(dāng)從函數(shù)返回局部變量或參數(shù)時,簡單地寫成return object;而不要使用std::move()。
- 在現(xiàn)代C++中,采用零原則(你應(yīng)該設(shè)計(jì)類使其不需要任意五大特殊成員函數(shù)[析構(gòu)函數(shù)、復(fù)制構(gòu)造函數(shù)、移動構(gòu)造函數(shù)、復(fù)制賦值運(yùn)算符函數(shù)、移動賦值運(yùn)算符函數(shù)])。五大特殊成員函數(shù)應(yīng)該僅被用于RAII類。
- 子類試圖重寫一個非虛函數(shù)會隱藏父類的定義。
- 虛函數(shù)在構(gòu)造函數(shù)/析構(gòu)函數(shù)中有不同行為。如果子類重寫了父類的一個虛函數(shù),那么從父類構(gòu)造函數(shù)/析構(gòu)函數(shù)中調(diào)用該方法會實(shí)際調(diào)用父類的實(shí)現(xiàn)版本而非子類的重寫版本。
- 總是讓析構(gòu)函數(shù)成為virtual。編譯器生成的默認(rèn)析構(gòu)函數(shù)不是virtual,所以你應(yīng)該定義(或顯式默認(rèn))一個虛析構(gòu)函數(shù),至少為父類。
- 向上類型轉(zhuǎn)換時,使用指向父類的指針或引用來避免切割。
- 僅當(dāng)必要時使用向下類型轉(zhuǎn)換,且確保使用dynamic_cast()。
- 你總是可以在類層次結(jié)構(gòu)中向上轉(zhuǎn)型,有時也可以向下轉(zhuǎn)型??鐚哟谓Y(jié)構(gòu)的轉(zhuǎn)型可以通過改變轉(zhuǎn)型運(yùn)算符函數(shù)的行為或使用reinterpret_cast()來實(shí)現(xiàn),但均不推薦。
- 為了避免奇怪的bug,你應(yīng)該重寫一個重載方法的所有版本。
- 如果子類不提供自己的復(fù)制構(gòu)造函數(shù)或復(fù)制賦值運(yùn)算符函數(shù),則父類的復(fù)制功能依然有效;但是如果子類提供自己的復(fù)制構(gòu)造函數(shù)或復(fù)制賦值運(yùn)算符函數(shù),則它需要顯式調(diào)用父類的版本。
- typeid運(yùn)算符僅當(dāng)類至少有一個虛函數(shù)時才有效;另外typeid運(yùn)算符會忽略參數(shù)的引用和const標(biāo)識符。
- 你可以使用reinterpret_cast()把指針轉(zhuǎn)換為整數(shù)或把整數(shù)轉(zhuǎn)換為指針。但是你只能把指針轉(zhuǎn)換為足夠大的整型。
- 模塊實(shí)現(xiàn)文件不可以export任何東西。只有模塊接口文件可以。
- 推薦使用匿名命名空間來完成內(nèi)部鏈接。
- 不同源文件的非局部變量的初始化順序是未定義的。
- 虛函數(shù)和析構(gòu)函數(shù)不可以是函數(shù)模板。
- path的append()和運(yùn)算符/=會自動添加平臺依賴的路徑分隔符,而concat()和運(yùn)算符+=不會。
- 你應(yīng)該捕獲并處理所有可能的異常。
- 當(dāng)動態(tài)捕獲異常時,確保按引用捕獲。如果按值捕獲,則有可能會切割對象,從而丟失對象信息。
- 使用throw;來重新拋出異常,不要使用throw e;來重新拋出異常e。
- 不小心的異常處理會導(dǎo)致內(nèi)存和資源泄漏。
- 使用智能指針或RAII類來解決內(nèi)存/資源泄漏問題,而不使用捕獲、清理、重新拋出的方法。
- 如果從構(gòu)造函數(shù)中拋出異常,則該對象的析構(gòu)函數(shù)不會被調(diào)用。
- 不要讓任何異常從析構(gòu)函數(shù)中逃離。
- 重載所有形式的operator new,或者顯式delete不需要的重載,來避免內(nèi)存分配的不一致性。
- vector類的insert()或erase()方法,當(dāng)傳入range參數(shù)時,需要滿足begin和end指向同一容器,并且end要大于等于begin。
C++ 20高級編程 WARNING
最后編輯于 :
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
相關(guān)閱讀更多精彩內(nèi)容
- 第二周講解的是仍然是object-based programming,以String類為例說明包含指針成員的類的寫...
- 7.Big Three:拷貝構(gòu)造,拷貝賦值,析構(gòu) (1)什么時候需要自己寫拷貝構(gòu)造和拷貝賦值函數(shù) 當(dāng)編譯器提供的默...
- 本周學(xué)習(xí)內(nèi)容回顧 轉(zhuǎn)換函數(shù) conversion function non-explicit-one-argume...
- 1.c++編程簡介 所需基礎(chǔ)知識 . 某種編程語言: 變量、類型、作用域、循環(huán)、流程控制 . 編譯、連結(jié)建立可執(zhí)行...
- 第二周 七、三大函數(shù) 1.三大函數(shù) Class without pointer member-complex Cl...