條款17以獨立語句將newed物件置入智慧指標
總結:
以獨立語句中將
new 出來的物件存入智慧指標。如果疏忽了這一點,當異常發生時,有可能導致難以察覺的資源洩漏。
假設我們有一個函式用來揭示處理程式的優先權,另一個函式用來在某動態分配所得的Widget上進行某些帶有優先權的處理:
int priority();
void processWidget(std::tr1::shared_ptr<Widget> pw, int priority);
不要忘記使用物件管理資源的至理名言,processWidget為處理動態分配的 Widget使用了一個智慧指標(在此採用tr1::shared_ptr)。現在考慮一個對processWidget 的呼叫:
processWidget(new Widget, priority());
以上呼叫不能通過編譯。tr1::shared_ptr建構函式需要一個原始指標,但該建構函式是個explicit建構函式,無法進行隱式轉換,所以不能從一個由"new Widget"返回的原始指標隱式轉換到 processWidget 所需要的 tr1::shared_ptr。如果寫成這樣就可以通過編譯:
processWidget(std::tr1::shared_ptr<Widget>(new Widget), priority());
令人驚訝的是,儘管我們在這裡使用了物件管理資源,這個呼叫還是可能洩漏資源。
在編譯器能生成一個對 processWidget 的呼叫之前,必須首先核算即將被傳遞的各個實參。在呼叫 processWidget之前,編譯器必須為這三件事情生成程式碼:
· 呼叫 priority。
· 執行 "new Widget"。
· 呼叫 tr1::shared_ptr 的建構函式。
C++ 編譯器允許在一個相當大的範圍內決定這三件事被完成的順序(這裡與 Java 和 C# 等語言的處理方式不同,那些語言裡函式引數總是按照一個特定順序被計算)。可以確定的是"new Widget"一定在 tr1::shared_ptr 建構函式被呼叫之前執行,因為這個表示式的結果要作為一個引數傳遞給 tr1::shared_ptr 的建構函式,但是 priority 的呼叫可以排在第一第二或第三個執行。如果編譯器選擇第二個執行它(或許能生成更有效率的程式碼),我們最終得到這樣一個操作順序:
1. 執行 "new Widget"。
2. 呼叫 priority。
3. 呼叫 tr1::shared_ptr 的建構函式。
現在如果對 priority 的呼叫引發一個異常將發生什麼?在這種情況下,從 "new Widget" 返回的指標被丟失,因為它沒有被存入我們期望能阻止資源洩漏的tr1::shared_ptr。由於一個異常可能插入“資源被建立(經由newWidget)”和“資源被轉換為資源管理物件”兩個時間點之間,所以呼叫processWidget可能會發生一次洩漏。
避免這類問題的方法很簡單:使用分離語句,分別寫出(1)建立Widget,(2)將它置入一個智慧指標內,然後再把那個智慧指標傳給processWidget:
std::tr1::shared_ptr<Widget> pw(newWidget);
// 在單獨語句內以智慧指標儲存newed所得物件
processWidget(pw, priority()); // 這個呼叫動作絕不至於造成洩漏
這樣做之所以行得通,是因為編譯器對於跨越語句的各項操作沒有重新排列的自由(只有在語句內才擁有那個自由度)。"new Widget" 表示式以及tr1::shared_ptr建構函式呼叫這兩個動作,與 priority的呼叫在不同的語句中,所以編譯器不得在它們之間任意選擇執行次序。
相關文章
- 條款13 以物件管理資源物件
- 滴水逆向筆記系列-c語言總結4-15.switch語句反彙編-16.指標1-17.指標2筆記C語言指標
- 藍芽衛生棉條:置入的智慧穿戴裝置藍芽
- 條件語句
- 獨立開發者專注一款app還是大量炮製以快速變現APP
- 智慧指標指標
- 縣域醫療崛起建設獨立檢驗中心成為硬指標指標
- More Effective C++ 條款17 (轉)C++
- 谷歌向亞馬遜echo下戰書:將獨立研發智慧音響谷歌亞馬遜
- GO 條件語句Go
- javaScript條件語句JavaScript
- 第十一章:使用智慧指標管理物件資源指標物件
- [CPP] 智慧指標指標
- C語言指標(三):陣列指標和字串指標C語言指標陣列字串
- 【C++系列】指標物件和物件指標的區別C++指標物件
- 什麼是智慧指標?為什麼要用智慧指標?指標
- 指向const物件的指標 和 const指標物件指標
- Go:條件控制語句Go
- if條件語句sed命令
- 04.條件語句
- 這款Level智慧湯勺能幫你實現獨立 自動保持平衡
- Python-條件語句和迴圈語句Python
- JavaScript 標籤語句JavaScript
- C語言(指標)C語言指標
- C語言指標C語言指標
- openfoam 智慧指標探索指標
- vtk智慧指標指標
- 智慧指標學習指標
- 【c++】智慧指標C++指標
- C++智慧指標C++指標
- C語言指標(二) 指標變數 ----by xhxhC語言指標變數
- 垃圾遊戲的17條評判標準遊戲
- 給獨立開發商的5條PR建議
- 很強的Sql語句測試題,能獨立做出來你的Sql就出師了SQL
- Windows 9可能將是最後獨立Windows版本Windows
- C語言指標安全及指標使用問題C語言指標
- 智慧指標之手撕共享指標shared_ptr指標
- Swift 條件語句講解Swift