Effective C++学习第四天
條款11:在operator=中處理自我賦值的現(xiàn)象
? ? ? ? ? ?雖然我們在平時可能不會出現(xiàn)顯示自我賦值的現(xiàn)象,當加入指針或者引用時,可能會出現(xiàn)不同的指針或引用指向同一對象(對象的不同別名),這時候我們就得考慮對象是否是同一個;考慮到要保證系統(tǒng)的自我賦值安全性和異常安全性的角度,可以采用的方案是:將原來的被賦值對象做一個副本,然后讓被賦值對象指向復制對象,最后刪除副本即可,代碼如下:
? ? ? ? widget& widget::operator=(const widget & rhs){
? ? ? ? ? ? ? ? ? ? bitmap *porig=pb;? ? ? ? ? ? ? ? ? ? ? ? ? //pb為類widget的一個類型為bitmap的指針
? ? ? ? ? ? ? ? ? ? pb=new? bitmap(*rhs.pb);
? ? ? ? ? ? ? ? ? ? delete porig;
? ? ? ? ? ? ? ? ? ? return *this;
? ? ? ? ? }
? ? ? ? ? ?最好的方法是采用copy and swap的方案,代碼如下:(方案1采用傳引用的方法,方案2采用傳值的方法
? ? ? ?void swap(widget &rhs)? {....};? ? //交換rhs和*this的數(shù)據(jù);
? ? 方案1: widget &widget::operator=(const widget & rhs){? ? ? ? ? ? ? 方案2: widget&widget::operator=(widget rhs)
? ? ? ? ? ? ? ? ? ? widget temp(rhs);? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? {? ?
? ? ? ? ? ? ? ? ? ? swap(temp);? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?swap(rhs);? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
? ? ? ? ? ? ? ? ? ?return *this;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? return *this;
? ? ? }? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }
條款12:復制對象時勿忘其每個成分
? ? ? ? ? 當自己定義copy函數(shù)時(copy構造和copy assignment),編譯器不再給我們提供新的copy函數(shù),因此在拷貝的過程中,我們要確定所有的成員變量都被拷貝;
? ? ? ? ? 當我們?yōu)閏lass增添新的成員變量時,我們需要修改我們所有的copy函數(shù),構造函數(shù),采用繼承的方式可以避免代碼的過多修改,但是你必須保證base class的成員變量也被初始化,也就是在derived class的拷貝函數(shù)初始化列表或者函數(shù)體中調用base class的拷貝函數(shù);如果不這樣做,derived class在構造copy函數(shù)的時候會調用base class的default copy函數(shù),但是base class的copy函數(shù)是被阻止的,因此此時編譯器會報錯;
? ? ? ? ?結論:當我們寫一個自定義的copy函數(shù)的時候,確定幾點:1)復制所有的local成員變量;2)調用所有base class內適當?shù)腸opy函數(shù);
? ? ? ? ? ? 不要令copy assignment去調用copy構造函數(shù);也不要讓copy構造函數(shù)去調用copy assignment;
? ? ? ? ? ?當copy assignment和copy 構造函數(shù)有相近的代碼時,可以把相同的代碼變成新的成員函數(shù),這樣的函數(shù)通常為private且常命名為init;
條款13:以對象管理資源
? ? ? ? ? ? ?以singleton(單例模式)的factory function為例,函數(shù)返回的是一個heap-base的指針,用戶在使用完這個對象之后需要把這個指針刪除,如何保證這個指針所指向的資源被刪除呢?可選用的方法是把:把資源放進對象中,利用C++的“析構函數(shù)自動調用機制”保證資源被釋放;
? ? ? ? ? ? ?C++標準程序庫中提供auto_ptr(類指針對象,也稱為智能指針),其析構函數(shù)自動對其所指對象調用delete,常見的智能指針有unique_ptr,shared_ptr;weak_ptr;
? ? ? ? ? ? 以對象管理資源的兩個關鍵想法:1)獲得資源后立刻放進管理對象內,實際上“以對象管理資源”的觀念通常被稱為“資源取得時機便是初始化時間(resource acquisition isinitialization RAII)”;2)管理對象運用析構函數(shù)確保資源被釋放(在析構函數(shù)釋放資源時,可能會出現(xiàn)異常,正確處理析構函數(shù)中拋出異常的情況);
? ? ? ? ? ? auto_ptr的特性是被銷毀(調用copy函數(shù)時會發(fā)生)時自動刪除它的所指之物,并將自己的指針指向nullptr,因此不要讓對個auto_ptr指向同一個對象,如果這樣可能會出現(xiàn)對象被刪除一次以上;auto_ptr的性質是始終只有一個指針取得資源的唯一擁有權;
? ? ? ? ? auto_ptr的替代方案是:引用型計數(shù)指針(reference-counting smart pointer,RCSP),該指針特性就是持續(xù)追蹤多個指針指向同一資源,并在無人指向該資源時釋放資源,但是RCSP無法打破環(huán)形引用(也就是類中互相指向的問題,可用weak_ptr來解決這一現(xiàn)象);
? ? ? ? ?由于以對象管理資源在析構函數(shù)中執(zhí)行的是delete而非delete[],因此動態(tài)分配的數(shù)組無法通過這種方式來實現(xiàn)內存釋放,只能通過自己手工釋放內存資源;
總結
以上是生活随笔為你收集整理的Effective C++学习第四天的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 有任务助手蓝总每日刷几盘能过
- 下一篇: Effective C++学习第五天