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

請牢記:java

以獨立語句將newed對象存儲於(置入)智能指針內。若是不這樣作,一旦異常被跑出來,有可能致使難以察覺的資源泄露。c++

 

假設有個函數用來處理程序的優先權,另外一個函數用來在某動態分配所得的Widget上進行某些帶有優先權的處理:c#

int priority();    //處理程序優先權的函數
void processWidget(std::tr1::shared_ptr<Widget> pw, int priority);//該函數在動態分配所得的Widget上進行某些帶有優先權的處理。

調用:函數

processWidget(new Widget, priority());     //編譯不過!該構造函數是explicit 沒法隱式轉換爲shared_ptr

所以能夠寫成:spa

processWidget(std::tr1::shared_ptr<Widget>(new Widget), priority());  //能夠編譯經過,可是...可能泄露資源。

後果:一旦發生異常,可能資源泄露指針

緣由:對象

在調用processWidget以前,編譯器必須建立代碼,執行三步:blog

(1)調用prority()ci

(2)執行"new Widget"資源

(3)調用 tr1"shared_ptr構造函數

可是c++調用順序跟java和c#不一樣,不是以特定順序完成。priority函數的調用有可能在第1、第二或者第三執行。當在第二位執行的狀況下:

(1)執行"new Widget"

(2)調用prority()

(3)調用 tr1"shared_ptr構造函數

若調用prority時發生異常,則"new Widget"返回的指針將會遺失,這樣會引起資源泄露。

解決方案:使用分離語句,分別寫出(1)建立Widget,(2)將它置入一個智能指針內,而後再把那個智能指針傳給processWidget:

std::tr1::shared_ptr<Widget> pw(new Widget);    //在單獨語句內以智能指針存儲newed所得對象
processWidget(pw, priority()); // 這個動做不會形成泄露

由於編譯器對於」跨越語句的各項操做「沒有從新排列的自由(只有在語句內編譯器才擁有那個自由度)。

相關文章
相關標籤/搜索