日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > c/c++ >内容正文

c/c++

Effective Modern C++笔记汇总

發(fā)布時(shí)間:2023/12/20 c/c++ 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Effective Modern C++笔记汇总 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

從 2016 年 8 月份開(kāi)始讀這本書(shū),限于目前大陸這邊還沒(méi)有中文版,所以是一邊讀一邊翻譯,但是自己的英語(yǔ)水平很一般,所以并沒(méi)有以翻譯的角度來(lái)寫(xiě)文章,怕自己的水平糟蹋了這本好書(shū),所以基本上就是讀懂了書(shū)中的意思,然后按照自己的理解寫(xiě)出來(lái),截止 2017 年 6 月 5 號(hào)已經(jīng)全部完成,目前是第一版,自己還在不斷調(diào)整語(yǔ)句、格式和內(nèi)容。力求不誤導(dǎo)人。也希望廣大的 C++愛(ài)好者可以給我提出一些修改建議。

Effective Modern C++ 目錄

Item1 Understand template type deduction

Tips:

  • 在模版類型推到的時(shí)候,如果傳遞的參數(shù)是引用類型,那么可以看作是非引用類型的,也就是說(shuō)類型的引用部分被忽略。
  • 當(dāng)對(duì)通用引用類型的參數(shù)進(jìn)行類型推導(dǎo)時(shí),左值參數(shù)需要特殊對(duì)待。
  • 當(dāng)推導(dǎo)正常的參數(shù)類型時(shí),const和volatile類型的參數(shù)會(huì)被忽略掉const和volatile部分。
  • 在模版類型推導(dǎo)時(shí),如果參數(shù)是數(shù)組或是函數(shù)名會(huì)退化為指針,除非這些參數(shù)是用來(lái)初始化 引用的。
  • Item2 Understand auto type deduction

    Tips:

  • auto類型推導(dǎo)通常和模版類型推導(dǎo)是一致的,但是auto類型推導(dǎo)對(duì)于{}會(huì)推導(dǎo)為std::initializer_list,但是模版類型無(wú)法對(duì)其進(jìn)行推導(dǎo)
  • auto對(duì)于函數(shù)返回值的類型推導(dǎo)和lambda參數(shù)類型推導(dǎo)時(shí)就是隱式的模版類型推導(dǎo),并不是auto類型推導(dǎo),對(duì)于{}無(wú)法進(jìn)行推導(dǎo)
  • Item3 Understand decltype

    Tips:

  • decltype推導(dǎo)出來(lái)的類型幾乎總是和目標(biāo)類型是一致的
  • 對(duì)于類型為T的左值表達(dá)式來(lái)說(shuō),decltype總是推導(dǎo)成T&
  • C++14支持decltype(auto)聲明變量和auto類似,可以對(duì)初始值進(jìn)行類型推導(dǎo),但是遵循的是decltype的規(guī)則
  • Item4 Know how to view deduced types

    Tips:

  • 類型推導(dǎo)可以借助于IDE,或者是編譯器的錯(cuò)誤輸出以及Boost TypeIndex庫(kù)
  • 一些工具的類型推導(dǎo)結(jié)果可能是對(duì)我們所有幫助的,但是不一定是準(zhǔn)確的,因此理解C++的類型推導(dǎo)規(guī)則仍然是必不可少的
  • Item5 Prefer auto to explicit type declarations

    Tips

  • auto變量必須初始化,可以緩解因?yàn)轭愋筒黄ヅ鋵?dǎo)致的可移植性或效率問(wèn)題,可以緩解在重構(gòu)過(guò)程中需要顯示輸入很長(zhǎng)的變量類型名稱。
  • auto類型的變量受制于Item2和Item6中提到的陷阱
  • Item6 Use the explicitly typed initializer idiom when auto deduces undesied types

    Tips

  • 對(duì)于一些看不見(jiàn)的proxy類型,使用auto對(duì)這類初始化表達(dá)式進(jìn)行類型推導(dǎo)會(huì)推導(dǎo)出錯(cuò)誤的類型
  • 通過(guò)顯示的類型初始化慣用法可以強(qiáng)制auto推導(dǎo)出目標(biāo)類型
  • Item7 Distinguish between () and {} when creating objects

    Tips

  • {}初始化是最廣泛的初始化語(yǔ)法,它可以阻止窄化轉(zhuǎn)換,并且避免了C++最復(fù)雜的語(yǔ)法解析
  • 在構(gòu)造函數(shù)做函數(shù)重載的時(shí)候,{}會(huì)優(yōu)先匹配帶有std::initializer_list參數(shù)的版本,即使其他構(gòu)造函數(shù)看起來(lái)更匹配
  • 對(duì)與std::vector兩個(gè)參數(shù)的構(gòu)造函數(shù)來(lái)說(shuō),其{}和()兩種初始化方式有很大的不同
  • 在模版中對(duì)于{}和()初始化如何進(jìn)行選擇是一個(gè)挑戰(zhàn)
  • Item8 Prefer nullptr to 0 and NULL

    Tips

  • 優(yōu)先使用nullptr替換0和NULL
  • 避免同時(shí)重載帶有整型參數(shù)和指針類型的參數(shù)
  • Item9 Prefer alias declarations to typedefs

    Tips

  • typedef 不支持模版化,但是using的別名聲明可以
  • 模版別名避免了傳統(tǒng)的typedef帶來(lái)的::type后綴,以及在類型引用的時(shí)候需要的typename前綴
  • C++14給所有的C++11模版類型萃取提供了別名
  • Item10 Prefer scoped enums to unscoped enums

    Tips

  • C++98種的枚舉眾所周知是無(wú)作用域限制的
  • C++11中的枚舉類是有作用域限制的,不能進(jìn)行隱式的類型轉(zhuǎn)換需要使用C++的類型cast進(jìn)行轉(zhuǎn)換
  • 無(wú)論是枚舉類還是傳統(tǒng)的枚舉類型都支持指定底層的存儲(chǔ),對(duì)于枚舉類來(lái)說(shuō)默認(rèn)的底層存儲(chǔ)類型是int,而傳統(tǒng)的枚舉類型其底層存儲(chǔ)是未知的,需要在編譯器進(jìn)行選擇
  • 枚舉類總是可以進(jìn)行前向聲明的,而枚舉類型則不行,必須是在明確指定其底層存儲(chǔ)的時(shí)候才能進(jìn)行前向聲明
  • Item11 Prefer deleted functions to private undefined ones

    Tips

  • 優(yōu)先使用delete來(lái)刪除函數(shù)替換放在私有作用域中未定義的
  • 任何函數(shù)都可以被刪除,包括非成員函數(shù),模版實(shí)例化等
  • Item12 Declare overriding function override

    Tips

  • 對(duì)于要重寫(xiě)的函數(shù)添加override關(guān)鍵字,讓編譯器負(fù)責(zé)檢查
  • 成員函數(shù)的引用標(biāo)識(shí)符可以識(shí)別出(*this)的不同,是左值類型,還是右值類型
  • Item13 Prefer const_iterators to iterators

    Tips

  • 優(yōu)先使用const_iterator替換iterator
  • 為了是代碼更通用,應(yīng)該優(yōu)先使用非成員函數(shù)版本的begin、end、cbegin、cend等
  • Item14 Declare functions noexcept if they won’t emit exception

    Tips

  • noexcept 是函數(shù)接口的一部分,這意味著調(diào)用者會(huì)依賴它
  • 使用noexcept聲明的函數(shù)相比于沒(méi)有使用noexcept聲明的函數(shù)代碼更具可優(yōu)化性
  • noexpect對(duì)于move、swap、內(nèi)存分配函數(shù)、析構(gòu)函數(shù)等具有特別的價(jià)值
  • 大多數(shù)函數(shù)都是異常中立的而不是noexcept
  • Item15 Use constexpr whenever possible

    Tips

  • constexpr對(duì)象是const,它的初始值是編譯期的
  • constexpr函數(shù)當(dāng)傳入的參數(shù)是編譯期值時(shí)可以產(chǎn)生編譯期的結(jié)果
  • constexpr對(duì)象和函數(shù)可以廣泛使用在非constexpr修飾的對(duì)象和函數(shù)上下文中
  • constexpr關(guān)鍵字是對(duì)象以及函數(shù)接口的一部分
  • Item16 Make const member functions thread safe

    Tips

  • 為了讓const成員函數(shù)是線程安全的,除非你確定不會(huì)在并發(fā)環(huán)境中調(diào)用
  • 使用std::atomic變量可能會(huì)提供比mutex更好的性能,但是它僅僅適合操作單個(gè)變量和內(nèi)存位置的操作
  • Item17 Understand special member function generation

    Tips

  • 編譯器可能會(huì)生成的特殊成員函數(shù)會(huì)有默認(rèn)構(gòu)造函數(shù)、析構(gòu)函數(shù)、拷貝操作、移動(dòng)操作等
  • 僅僅當(dāng)類沒(méi)有顯式的聲明移動(dòng)操作、拷貝操作和析構(gòu)函數(shù)的時(shí)候,編譯器才會(huì)生成默認(rèn)的移動(dòng)構(gòu)造函數(shù)
  • 僅僅當(dāng)類沒(méi)有顯式的聲明拷貝構(gòu)造函數(shù)、或是聲明了移動(dòng)構(gòu)造函數(shù)時(shí)編譯器才會(huì)生成默認(rèn)的拷貝構(gòu)造函數(shù),和拷貝構(gòu)造函數(shù)類似,僅僅當(dāng)類沒(méi)有顯式的聲明拷貝賦值操作符或是移動(dòng)構(gòu)造操作符時(shí)編譯器才會(huì)生成默認(rèn)的拷貝賦值操作符,不建議在具有明確聲明的析構(gòu)函數(shù)的類中生成復(fù)制操作。
  • 成員函數(shù)模版不會(huì)阻止編譯器生成特殊的成員函數(shù)
  • Item18 Use std::unique_ptr for exclusive-ownership resource management

    Tips

  • std::unique_ptr很小、很快、是一個(gè)只能移動(dòng)的,獨(dú)占管理資源的智能指針。
  • 默認(rèn)情況看下資源的刪除使用的是delete,但是可以定制刪除器,有狀態(tài)的刪除器會(huì)導(dǎo)致std::unique_ptr對(duì)象的大小增長(zhǎng)。
  • 將std::unique_ptr轉(zhuǎn)換為std::shared_ptr是很容易的
  • Item19 Use std::shared_ptr for shared-ownership resource management

    Tips

  • std::shared_ptr提供了方便的方法進(jìn)行垃圾回收可以對(duì)任意共享資源的生命周期進(jìn)行管理。
  • 相比于std::unique_ptr,std::shared_ptr對(duì)象通常情況下要大兩倍,這是因?yàn)樗峙湟粋€(gè)控制塊,該控制塊中包含了一個(gè)原子類型的引用計(jì)數(shù)、刪除器、弱引用計(jì)數(shù)等
  • 默認(rèn)的資源釋放是通過(guò)delete,但是std::shared_ptr支持自定義刪除器,并且刪除器的類型不影響std::share_ptr的類型和大小。
  • 避免從一個(gè)指針類型的變量創(chuàng)建std::shared_ptr
  • Item20 Use std::weak_ptr for std::shared_ptr like pointers that can dangle

    Tips

  • std::weak_ptr可以探查std::shared_ptr指向的指針是否是懸掛指針
  • 使用std::weak_ptr的一些潛在的場(chǎng)景包括,對(duì)象緩存、觀察者模式、阻止std::shared_ptr的循環(huán)引用
  • Item21 Perfer std::make_unique and std::make_shared to direct use of new

    Tips

  • 相比于直接使用new,make系列的函數(shù)消除了源代碼重復(fù)、提升了異常安全性,并且std::make_shared和std::allocate_shared生成的代碼更小更快
  • 對(duì)于希望自定義刪除器以及通過(guò){}進(jìn)行初始值的設(shè)定時(shí),不適合使用make系列函數(shù)
  • 對(duì)于std::shared_ptr來(lái)說(shuō)有兩類場(chǎng)景不適合使用make系列函數(shù),第一個(gè)就是需要自定義管理內(nèi)存的,第二個(gè)就是管理大對(duì)象時(shí),并且存在std::weak_ptr比std::shared_ptr生命周期更長(zhǎng)的情況
  • Item22 When using the Pimpl, define specific member functions in the implementation file

    Tips

  • Pimpl的慣用法通過(guò)減少類的使用者對(duì)類實(shí)現(xiàn)的編譯依賴從而縮小編譯所花費(fèi)的時(shí)間
  • pImpl使用std::unique_ptr時(shí),類的特殊函數(shù)聲明放在頭文件中,具體實(shí)現(xiàn)放在實(shí)現(xiàn)文件中的,避免了頭文件中包含了std::unique_ptr析構(gòu)相關(guān)的函數(shù),導(dǎo)致編譯錯(cuò)誤
  • 上面的建議適用于std::unique_ptr,但是不適用于std::shared_ptr
  • Item23 Understand std::move and std::forward

    Tips

  • std::move的實(shí)現(xiàn)其實(shí)是一個(gè)無(wú)條件將類型cast轉(zhuǎn)換為右值類型,就本身而言沒(méi)有移動(dòng)任何東西
  • std::forward就是根據(jù)參數(shù)的類型有條件的進(jìn)行cast轉(zhuǎn)換,如果輸入的參數(shù)是一個(gè)右值就轉(zhuǎn)換為右值,否則就轉(zhuǎn)換為左值
  • 無(wú)論是std::move還是std::forward在運(yùn)行時(shí)都沒(méi)有做任何事情
  • Item24 Distinguish universal references from rvalues reference

    Tips

  • 如果一個(gè)模版函數(shù)的參數(shù)類型是T&&,并且T的類型是推導(dǎo)出來(lái)的,或者一個(gè)對(duì)象使用auto&&這樣的聲明,那么這個(gè)函數(shù)的參數(shù)和要聲明的對(duì)象都是通用引用類型
  • 如果類型的聲明不是type&&,或者沒(méi)有發(fā)生類型推導(dǎo),那么type&&表示的是一個(gè)右值引用
  • 如果通用引用初始化的時(shí)候傳入的是一個(gè)右值,那么就和右值引用一樣,如果傳入的是左值那么就喝左值引用是一樣的
  • Item25 Use std::move on rvalue reference, std::forward on universal references

    Tips

  • 應(yīng)用std::move到右值引用,std::forward到通用引用
  • 對(duì)于右值引用和通用引用作為值從函數(shù)返回時(shí)本質(zhì)上都是做了相同的事情
  • 如果希望通過(guò)編譯器進(jìn)行返回值優(yōu)化,則不要將std::move或std::forward應(yīng)用到局部對(duì)象
  • Item26 Avoid overloading on universal references

    Tips

  • 在通用引用上進(jìn)行重載,幾乎總是會(huì)導(dǎo)致通用引用重載的版本比預(yù)期被調(diào)用的次數(shù)更頻繁。
  • 完美轉(zhuǎn)發(fā)構(gòu)造函數(shù)是非常有問(wèn)題的,因?yàn)樗鼈兺ǔ1确莄onst左值的拷貝構(gòu)造函數(shù)更好地匹配,并且可以劫持派生類對(duì)基類拷貝構(gòu)造和移動(dòng)構(gòu)造函數(shù)的調(diào)用。
  • Item27 Familiarize yourself with alternatives to overloading on universal references
    Item28 Understand reference collapsing
    Item29 Assume that move operations are not present,not cheap,and not used
    Item30 Familiarize yourself with perfect forwarding failure cases
    Item31 Avoid default capture modes
    Item32 Use Init capture to move objects into closures
    Item33 Use decltype on auto&& parameters to std::forward them
    Item34 Prefer lambdas to std::bind
    Item35 Prefer task-based programming to thread- based
    Item36 Specify std::launch::async if asynchronicity is essential
    Item37 Make std::threads unjoinable on all paths
    Item38 Be aware of varying thread handle destructor behavior
    Item39 Consider void futures for one-shot event communication
    Item40 Use std::atomic for concurrency, volatile for specific memory
    Item41 Consider pass by value for copyable parameters that are cheap to move and always copied.
    Item42 Consider emplacement instead of insertion

    總結(jié)

    以上是生活随笔為你收集整理的Effective Modern C++笔记汇总的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。