C++17代码整洁之道
C++17代碼整潔之道
C++代碼整潔的基本規(guī)范
良好的命名
- 名稱(chēng)應(yīng)該自解釋
- 使用域中的名稱(chēng)
- 避免使用匈牙利命名法(即名稱(chēng)前加類(lèi)型)
- 不要通過(guò)注釋禁用代碼
函數(shù)
-
只做一件事情
-
函數(shù)體量要小
-
當(dāng)你為函數(shù)找到一個(gè)富有表現(xiàn)力的名稱(chēng)時(shí),名稱(chēng)中沒(méi)有連詞
-
圈復(fù)雜度低
-
函數(shù)的參數(shù)要少
-
-
函數(shù)盡可能小
函數(shù)應(yīng)該很小,45行,做多1215行,不能再多了
-
使用容易理解的函數(shù)名
std::string head = html.substr(...);引入一個(gè)有意圖的名稱(chēng),將更加容易理解
std::string extractHtmlHeader(const std::string& html) {retrun html.substr(); } -
函數(shù)的參數(shù)和返回值
-
函數(shù)的參數(shù)越少越好
-
函數(shù)中最好不要有標(biāo)志參數(shù)bool
使用bool類(lèi)型說(shuō)明你很有可能需要在函數(shù)中做判斷,那為什么不分別用兩個(gè)函數(shù)處理兩種情況呢
-
避免使用輸出參數(shù),如果要返回多個(gè)參數(shù)請(qǐng)使用std::tuple
-
不要傳遞或者返回NULL或nullptr
原因:
- 導(dǎo)致很多空檢查,增加代碼復(fù)雜性
- 對(duì)象所有權(quán)問(wèn)題
-
-
首先在棧上構(gòu)造對(duì)象而不是在堆上
在堆上創(chuàng)建對(duì)象給創(chuàng)建者增加了管理資源的責(zé)任,而原來(lái)所擔(dān)心的昂貴的拷貝構(gòu)造成本也不需要擔(dān)心了,因?yàn)镃++11增加了std::move()移動(dòng)語(yǔ)義,即允許資源從一個(gè)對(duì)象"移動(dòng)"到另一個(gè)對(duì)象
-
在函數(shù)的參數(shù)列表中用**const引用代替指針**
-
如果一定要使用指針,請(qǐng)使用智能指針
-
盡量使用`const
用C++類(lèi)型轉(zhuǎn)換代替C風(fēng)格類(lèi)型轉(zhuǎn)換
C風(fēng)格:
float x{3.12}; int i = int(x);缺陷:不會(huì)在編譯期進(jìn)行類(lèi)型檢查可能產(chǎn)生錯(cuò)誤
C++風(fēng)格
int i = static_cast<int>(x);優(yōu)點(diǎn):在編譯期進(jìn)行類(lèi)型檢查
現(xiàn)代C++的高級(jí)概念
資源管理
-
資源申請(qǐng)即初始化
構(gòu)造時(shí)獲得,析構(gòu)時(shí)釋放
class Res final { public:Res() { sourse = new T(); }~Res() { delete sourse; } private:T* sourse; }; -
智能指針
-
具有獨(dú)占所有權(quán)的std::unique_ptr<T>
一個(gè)對(duì)象只能由一個(gè)std::unique_ptr<T>占有
class person { public: private:int age; }; std::unique_ptr<person> p1{ std::make_unique<person>() }; //類(lèi)型推導(dǎo)更加的簡(jiǎn)潔 auto p2{ std::make_unique<person>() };不允許調(diào)用std::unique<T>拷貝構(gòu)造函數(shù),但可以使用std::move將所持有的資源移動(dòng)給另一個(gè)std::unique<T>,將在后續(xù)部分進(jìn)行講解
-
具有共享所有權(quán)的std::shared_ptr<T>
std::shared_ptr<T>可以與其他std::shared_ptr<T>實(shí)例共享資源的所有權(quán)
std::shared_ptr<T>提供簡(jiǎn)單且有限的垃圾回收功能,內(nèi)部存在一個(gè)引用計(jì)數(shù)器
std::shared_ptr<person> s1 = std::make_shared<person>(); std::shared_ptr<person> s2; s2 = std::move(s1);上面例子并沒(méi)有修改智能指針計(jì)數(shù),但在移動(dòng)之后必須要小心使用s1,因?yàn)樗赡苁强盏?*(持有nullptr)**
3.無(wú)所有權(quán)但是能安全訪問(wèn)的std::weak_ptr<T>
? 他對(duì)資源的生命周期沒(méi)有影響std::weak_ptr<T>僅僅觀察他所指向的資源
-
避免顯式的new和delete
new和delete會(huì)增加代碼的復(fù)雜度: 當(dāng)不可避免的使用new和delete時(shí),你必須處理異常情形
顯式的調(diào)用new和delete可以通過(guò)以下措施避免
- 盡可能使用棧內(nèi)存,棧內(nèi)存永遠(yuǎn)不會(huì)泄露
- 用make function分配內(nèi)存
- 盡量使用容器
-
管理特有資源
Move語(yǔ)義
什么是move語(yǔ)義呢?在許多情況下,舊的C++強(qiáng)迫我們使用復(fù)制構(gòu)造函數(shù),實(shí)際上我們并不想要對(duì)象的深拷貝,相反,我們只移動(dòng)對(duì)象的負(fù)載就可以使用std::move
-
左值與右值的關(guān)系
左值與右值是歷史術(shù)語(yǔ)(這個(gè)翻譯的屬實(shí)垃圾)
左值更好的解釋是:一個(gè)locator value,一個(gè)在內(nèi)存有位置的對(duì)象
相對(duì)于左值,右值是一個(gè)不是左值的對(duì)象,右值是一個(gè)臨時(shí)對(duì)象或者是子對(duì)象
字面值 42 是一個(gè)右值。在內(nèi)存中沒(méi)有可標(biāo)識(shí)的位置,所以不能為他賦值,當(dāng)然,右值也可以占用棧上的數(shù)據(jù)區(qū)內(nèi)存,但是這個(gè)內(nèi)存是臨時(shí)分配的,而且復(fù)制完成后就會(huì)馬上釋放
-
右值引用
右值引用使優(yōu)定位右值的內(nèi)存成為可能,并且可以修改
int&& temp = 12 + 34; int* p1 = &temp; *p1 = 999; -
少用std::move()
編譯器自己會(huì)優(yōu)化,自己少用
-
零原則
**缺陷:**違反了五大原則copy/move構(gòu)造器以及copy/move賦值運(yùn)算符都沒(méi)有顯示定義
int main() {Mystring astring("test",4);Mystring anotherstring{astring};return 0; }在這個(gè)實(shí)例中,我們拷貝的對(duì)象是存儲(chǔ)字符串的地址指針,而不是內(nèi)存中指針指向的對(duì)象。
這就意味著,自動(dòng)調(diào)用默認(rèn)的復(fù)制構(gòu)造函數(shù)后,兩個(gè)對(duì)象指向同一個(gè)內(nèi)存,如果對(duì)象析構(gòu),將會(huì)導(dǎo)致雙重刪除,會(huì)造成嚴(yán)重的后果。
**零原則:**在你實(shí)現(xiàn)類(lèi)的時(shí)候,應(yīng)該不需要聲明或定義析構(gòu)函數(shù),拷貝構(gòu)造賦值函數(shù),移動(dòng)構(gòu)造賦值函數(shù)。用C++智能指針來(lái)管理資源
面向?qū)ο?/h2>
類(lèi)的設(shè)計(jì)原則
我太菜,以后理解到了再寫(xiě)
總結(jié)
以上是生活随笔為你收集整理的C++17代码整洁之道的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: @Scheduled
- 下一篇: springmvc 中文文档