欧美亚洲综合另类成人|亚洲国产夜色在线观看|中文亚字幕无码视频一区|韩国亚洲精品a在线无码|午夜亚洲一区二区亚洲福利|又粗又硬又黄又大免费观看|人妻少妇被猛烈进入中文字幕|超碰国产精品久久国产精品99

您現(xiàn)在的位置是: 產(chǎn)經(jīng) > > 正文

《EffectiveC++》讀書筆記(2):構(gòu)造/析構(gòu)/賦值運算_全球要聞

時間:2023-06-17 10:08:21 來源:面包芯語 發(fā)布者:DN032

點擊上方“C語言與CPP編程”,選擇“關(guān)注/置頂/星標公眾號”

干貨福利,第一時間送達!最近有小伙伴說沒有收到當天的文章推送,這是因為微信改了推送機制,確實會一部分有小伙伴刷不到當天的文章,一些比較實用的知識和信息,錯過了就是錯過了。所以建議大家加個星標??,就能第一時間收到推送了。

小伙伴們大家好,我是飛宇。


(資料圖)

今天繼續(xù)更新《Effective C++》和《C++并發(fā)編程實戰(zhàn)》的讀書筆記,下面是已經(jīng)更新過的內(nèi)容:

《C++并發(fā)編程實戰(zhàn)》讀書筆記(1):并發(fā)、線程管控

《C++并發(fā)編程實戰(zhàn)》讀書筆記(2):并發(fā)操作的同步

《Effective C++》讀書筆記(1):讓自己習慣C++

條款5、了解C++默認編寫并調(diào)用哪些函數(shù)

通常情況下,如果代碼中沒有聲明構(gòu)造函數(shù)、拷貝構(gòu)造函數(shù)、拷貝運算符、析構(gòu)函數(shù),編譯器會在需要時創(chuàng)建他們,但這往往只能滿足編譯器的需求,很可能無法滿足程序的需求。

實際的生成規(guī)則復雜一些,可以查閱cppreference。

編譯器生成的構(gòu)造函數(shù)/析構(gòu)函數(shù)是只是調(diào)用基類和非靜態(tài)成員變量的構(gòu)造函數(shù)/析構(gòu)函數(shù);生成的析構(gòu)函數(shù)是非虛的,除非基類有虛析構(gòu)函數(shù)。

至于生成的拷貝構(gòu)造函數(shù)和拷貝操作符只是單純將每個非靜態(tài)成員變量拷貝;有const成員或者引用成員時,以及基類拒絕拷貝操作符時,默認生成的拷貝操作符沒有意義,必須自己定義。

條款6、若不想使用編譯器自動生成的函數(shù),就該明確拒絕

很多時候,你并不希望某些類被拷貝,而僅僅不實現(xiàn)拷貝構(gòu)造/拷貝運算符是不夠的,因為編譯器可能會自行生成。

為此,可以把拷貝構(gòu)造/拷貝運算符聲明為"=delete",或者聲明為private(后者較為過時)。

事實上,對于析構(gòu)函數(shù)中需要釋放資源的類,為了防止內(nèi)存問題,除非真的需要拷貝功能,否則最好都禁止拷貝。

可以讓它們繼承上面的類,即可禁止編譯器生成拷貝操作:編譯器試圖為它們生成拷貝構(gòu)造/拷貝運算符時會嘗試調(diào)用基類Uncopyable的對應操作,而這會被拒絕。

條款7、為多態(tài)基類聲明virtual析構(gòu)函數(shù)

C++中多態(tài)性質(zhì)體現(xiàn)于虛函數(shù):基類指針或引用調(diào)用虛函數(shù)時會檢查指向的對象是基類還是派生類,再調(diào)用對應的函數(shù)。其具體實現(xiàn)這里不再贅述。

當這樣的一個指向派生類的基類指針析構(gòu)時,如果析構(gòu)函數(shù)不是虛函數(shù),則直接調(diào)用基類的析構(gòu)函數(shù),那么派生類獲取的資源未釋放,則會造成內(nèi)存泄漏。

而當析構(gòu)函數(shù)是虛函數(shù)時則先調(diào)用對應的派生類析構(gòu)函數(shù),再調(diào)用基類析構(gòu)函數(shù),資源全部釋放。

不過這種操作只有在基類是多態(tài)用途時才需要注意,也有很多類不是為了多態(tài)的用途,例如STL容器和上文的Uncopyable。

條款8、別讓異常逃離析構(gòu)函數(shù)

C++中拋出異常時會逐步展開其函數(shù)調(diào)用棧,清空局部資源,直到異常被catch。

如果析構(gòu)函數(shù)可以拋出異常,那么清空局部資源時局部對象的析構(gòu)函數(shù)再次異常時同時存在兩個異常,C++無法處理,可能會過早結(jié)束或出現(xiàn)不明確行為。因此,析構(gòu)函數(shù)絕對不要拋出異常,應通過try-catch捕獲任何異常。

有時,客戶需要處理某些異常,那么類應該提供一個普通成員函數(shù)執(zhí)行相關(guān)操作,供用戶調(diào)用并處理異常。

例如數(shù)據(jù)庫連接這樣的類中,假設用戶需要處理關(guān)閉連接時的異常,同時析構(gòu)函數(shù)不能拋出異常,可以這樣:

條款9、絕不在構(gòu)造和析構(gòu)過程中調(diào)用virtual函數(shù)

C++的構(gòu)造過程是先構(gòu)造基類再構(gòu)造子類、先初始化再進入構(gòu)造函數(shù)體;析構(gòu)過程相反。

對于派生類的構(gòu)造函數(shù)而言,進入其中時基類部分已構(gòu)造完而派生類部分未構(gòu)造完,對象類型是基類,故而此時調(diào)用虛函數(shù),實際上使用的是基類的虛函數(shù)。

析構(gòu)函數(shù)同理。進入析構(gòu)函數(shù)后派生類部分呈未定義值,對象類型是基類,調(diào)用的是基類的虛函數(shù)。

總而言之,在構(gòu)造函數(shù)與析構(gòu)函數(shù)中虛函數(shù)的行為有特殊變化;為了避免出錯,不要在其過程中使用虛函數(shù)。如果真的有需求,可以改造成非虛函數(shù)再使用。

條款10、令operator=返回一個reference to *this

C++中通常支持連鎖賦值,采用右結(jié)合律:

為了支持這個常規(guī),拷貝運算符需要返回一個引用。這一條款并不強制,但約定俗成。

條款11、在operator=中處理“自我賦值”

考慮這樣一個類,其中管理了一個堆對象

總有些時候,會出現(xiàn)實質(zhì)上“a=a”這種自我賦值的情況。那么這樣簡單的拷貝運算符就會出錯,先釋放了自身的pb,又使用了pb:

傳統(tǒng)做法是函數(shù)開頭添加一個測試:

這種做法具備“自我賦值安全性”,但不具備“異常安全性”:例如當new Bitmap異常時,pb指向被刪除的內(nèi)存。

常用的方法有兩種,兼顧了“自我賦值安全性”與“異常安全性”:

條款12、復制對象時勿忘其每一個成分

當自己實現(xiàn)拷貝構(gòu)造/拷貝運算符時,編譯器不會警告你遺漏了某些成員變量。因此,必須仔細地復制所有派生類成員,并調(diào)用基類的拷貝操作來復制基類成員。

拷貝構(gòu)造和拷貝運算符中很可能有相當多重復的操作,但因為兩個函數(shù)性質(zhì)完全不同,因此不能用其中一個調(diào)用另一個來減少冗余。

可以把共同功能放在第三個函數(shù)中,并由兩個拷貝操作共同調(diào)用。

你好,我是飛宇,本碩均于某中流985 CS就讀,先后于百度搜索以及字節(jié)跳動電商等部門擔任Linux C/C++后端研發(fā)工程師。

同時,我也是知乎博主@韓飛宇,日常分享C/C++、計算機學習經(jīng)驗、工作體會,歡迎點擊此處查看我以前的學習筆記&經(jīng)驗&分享的資源。

有個朋友收集了一些C++開發(fā)手冊、LeetCode刷題模板等精品資料,可加他的微信免費領(lǐng)取。

標簽:

搶先讀

相關(guān)文章

熱文推薦

精彩放送

關(guān)于我們| 聯(lián)系我們| 投稿合作| 法律聲明| 廣告投放

版權(quán)所有© 2011-2023  產(chǎn)業(yè)研究網(wǎng)  www.ty3637.com

所載文章、數(shù)據(jù)僅供參考.本站不作任何非法律允許范圍內(nèi)服務!

聯(lián)系我們:39 60 29 14 2 @qq.com

皖I(lǐng)CP備2022009963號-13