国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發(fā)設(shè)計 > 正文

C++箴言:將new出來的對象存入智能指針

2019-11-17 05:12:07
字體:
供稿:網(wǎng)友

  假設(shè)我們有一個函數(shù)取得我們的處理優(yōu)先級,而第二個函數(shù)根據(jù)優(yōu)先級針對動態(tài)分配的 Widget 做一些處理:

int PRiority();
void processWidget(std::tr1::shared_ptr<Widget> pw, int priority);
  不要忘記使用對象治理資源的至理名言,processWidget 為處理動態(tài)分配的 Widget 使用了一個智能指針(在此,是一個 tr1::shared_ptr)。

  現(xiàn)在考慮一個對 processWidget 的調(diào)用:

processWidget(new Widget, priority());
  且慢,別想這樣調(diào)用。它不能編譯。tr1::shared_ptr 的構(gòu)造函數(shù)取得一個裸指針(raw pointer)應(yīng)該是顯式的,所以不能從一個由 "new Widget" 返回的裸指針隱式轉(zhuǎn)型到 processWidget 所需要的 tr1::shared_ptr。下面的代碼,無論如何,是可以編譯的:

processWidget(std::tr1::shared_ptr<Widget>(new Widget), priority());
  令人驚奇的是,盡管我們在這里各處都使用了對象治理資源,這個調(diào)用還是可能泄漏資源。下面就來說明這是如何發(fā)生的。

  在編譯器能生成一個對 processWidget 的調(diào)用之前,它們必須傳遞實際參數(shù)來計算形式參數(shù)的值。第二個實際參數(shù)不過是對函數(shù) priority 的調(diào)用,但是第一個實際參數(shù)("std::tr1::shared_ptr<Widget>(new Widget)"),由兩部分組成

  ·表達式 "new Widget" 的執(zhí)行。

  ·一個對 tr1::shared_ptr 的構(gòu)造函數(shù)的調(diào)用。

  在 processWidget 能被調(diào)用之前,編譯器必須為這三件事情生成代碼:

  ·調(diào)用 priority。
 
  ·執(zhí)行 "new Widget"。

  ·調(diào)用 tr1::shared_ptr 的構(gòu)造函數(shù)。

  C++ 編譯器答應(yīng)在一個相當大的范圍內(nèi)決定這三件事被完成的順序。(這里與 java 和 C# 等語言的處理方式不同,那些語言里函數(shù)參數(shù)總是按照一個精確的順序被計算。)"new Widget" 表達式一定在 tr1::shared_ptr 的構(gòu)造函數(shù)能被調(diào)用之前執(zhí)行,因為這個表達式的結(jié)果要作為一個參數(shù)傳遞給 tr1::shared_ptr 的構(gòu)造函數(shù),但是 priority 的調(diào)用可以被第一個,第二個或第三個執(zhí)行。假如編譯器選擇第二個執(zhí)行它(大概這樣能使它們生成更有效率的代碼),我們最終得到這樣一個操作順序:

  ·執(zhí)行 "new Widget"。

  ·調(diào)用 priority。

  ·調(diào)用 tr1::shared_ptr 的構(gòu)造函數(shù)。

  但是請考慮,假如對 priority 的調(diào)用引發(fā)一個異常將發(fā)生什么。在這種情況下,從 "new Widget" 返回的指針被丟失,因為它沒有被存入我們期望能阻止資源泄漏的 tr1::shared_ptr。由于一個異常可能插入資源創(chuàng)建的時間和將資源交給一個資源治理對象的時間之間,所以調(diào)用 processWidget 可能會發(fā)生一次泄漏。 避免類似問題的方法很簡單:用一個單獨的語句創(chuàng)建 Widget 并將它存入一個智能指針,然后將這個智能指針傳遞給 processWidget:

std::tr1::shared_ptr<Widget> pw(new Widget); // store newed object
// in a smart pointer in a
// standalone statement

processWidget(pw, priority()); // this call won’t leak
  這樣做是因為編譯器在不同的語句之間重新安排操作順序的活動余地比在一個語句之內(nèi)要小得多。"new Widget" 表達式和 tr1::shared_ptr 的構(gòu)造函數(shù)的調(diào)用與 priority 的調(diào)用在不同的語句中,所以編譯器不會答應(yīng) priority 的調(diào)用插入它們中間。

  Things to Remember

  ·在一個獨立的語句中將 new 出來的對象存入智能指針。假如疏忽了這一點,當異常發(fā)生時,可能引起微妙的資源泄漏。 更多文章 更多內(nèi)容請看C/C++技術(shù)專題專題,或

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 武山县| 尼玛县| 桐城市| 平南县| 宜昌市| 清水县| 普兰县| 建宁县| 吉水县| 上犹县| 衡东县| 钦州市| 镇远县| 江门市| 霍州市| 兴文县| 阿合奇县| 治多县| 南澳县| 昌江| 洞头县| 从江县| 兴仁县| 伊宁县| 肃南| 洪洞县| 陇川县| 岗巴县| 山丹县| 桐梓县| 平塘县| 营口市| 和林格尔县| 密云县| 简阳市| 云龙县| 惠来县| 昂仁县| 济宁市| 响水县| 兰坪|