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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

Effective C++学习第五天

發布時間:2023/11/30 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Effective C++学习第五天 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

條款14:在資源管理類中小心copy行為

? ? ? ? ? 當我們深入理解“資源取得時機是初始化時機(RAII)”概念,并以此作為“資源管理類”的核心時,我們可能會遇到將RAII對象復制的情況,一般有兩種情況處理這個現象:1)如果我們的RAII對象是唯一的,那么復制就不合理,因此我們應該禁止copy構造的行為,正確的處理方式:將copy函數定義為private(base class),并用derived class private繼承這個函數來阻止copy行為;? 2)使用引用計數法,即智能指針的形式來實現對所有拷貝資源的追蹤,但是智能指針的缺省行為是當引用次數為0時刪除其所指向的對象。如果我們要實現的功能不是釋放資源,這時候就應該自定義智能指針的deleter(一個函數或者函數對象),當引用次數為0時調用這個函數實現相應功能,如:

class lock{

public:

? ? ? ? ?explicit lock(mutex *pm) : mutexptr(pm,unlock) { }? //用mutex初始化shared_ptr,并以unlock函數為刪除器

private:

? ? ? ? ? ? ? ? ?std::tr1::shared_ptr<mutex>mutexptr;

};

另外,上述例子中不需要聲明析構函數,因為class 析構函數會自動調用其non-static成員變量的析構函數;3)復制底部資源,采用深度拷貝的方法;4)采用轉移底部資源擁有權的方法,也就是所謂的auto_ptr指針;

條款15:在資源管理類中提供對原始資源的訪問

? ? ? ? ? 當你需要訪問一個RAII class對象的內部原始資源時,有兩種方法可以達成目標:1)在類的內部提供一個get成員函數,用來執行顯示轉換,也就是返回類內部指針的原始復件;2)允許隱式轉換到底部原始指針;在智能指針中,重載了指針取值操作符(operator->和operator*)來實現隱式轉換;對于一般的來說,可以在類中提供一個隱式轉換函數;如:

class font{

public:? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //顯示轉換函數:

? ? ? ? ? ? explicit font(fonthandle fh) : f(fh){ }? ? ? ? ? ? ? ? fonthandle get() const {? ?return f;? }

? ? ? ? ? ? ~font() { releasefont(f); }? ? ? ? ? ? ? ? ? ? ? ? ? ? //隱式轉換函數??

private:? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?operator fonthandle() const {return f;}//沒太明白怎么隱式轉換的

? ? ? ? ? fonthandle f;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //operator起到什么作用?

}

//顯示轉換? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//隱式轉換

void changefontsize(fonthandle f,int newsize);? ? ? ? ??void changefontsize(fonthandle f,int newsize);

font f(getfont());? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?font f(getfont());

changefontsize ( f.get(), newfontsize);? ? ? ? ? ? ? ? ? ? ??changefontsize ( f, newfontsize);

//但隱式轉換會出一個問題

font f1(getfont());? ??

fonthandle f2=f1;? ?//原意是拷貝,結果是f1先轉化為底部的fonthandle,然后拷貝,一旦此時f1被銷毀,f2就處于指向資源被釋放的狀態(dangle)

條款16:成對使用new和delete時采取相同的方式

? ? ? ? ? ? ? ?如果你在new的表達式中使用[ ],則必須在相應的delete表達式中也使用[ ],如果沒有使用[ ],那么也一定不要在delete中使用[ ];

條款17:以單獨語句將newed對象置入智能指針中

? ? ? ? ? 對于以下代碼分析;

? ? ? ? ? ? int priority( );

? ? ? ? ? ?void processwidget(std :: tr1 :: shared_ptr<wideget>pw,int priority);

? ? ? ? ? ? //調用時? ?processwidget(new widget, priority( ));//編譯錯誤,shared_ptr構造函數是explicit類型,不允許隱式轉換

? ? ? ? ? ?//processwidget(std :: tr1 ::?shared_ptr<wideget>(new widget),priority( ) );

? ? ? ? ? ?這個函數在調用processwidget之前,編譯器必須創建代碼,完成以下三件事情:1)調用priority;2)執行new widget;3)調用 std::tr1::shared_ptr構造函數;但是1)和2)的執行順序和編譯器有關,如果先執行2)后執行1),且在執行1)的時候發生異常,那么new widget返回的指針就會失效,那么內存泄露就產生了;

? ? ? ? ? 解決上述問題的方法:使用分離語句,把創建對象和給智能指針賦初值的語句分離出來,原因是:編譯器對于“跨越語句的各項操作”沒有重新排列的自由(只有在語句內才擁有那個自由度);代碼如下:

? ? ? ? ?std::tr1::shared_ptr<widget>pw(new widget);

? ? ? ? ? processwidget(pw,priority( ));

總結

以上是生活随笔為你收集整理的Effective C++学习第五天的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。