1. 程式人生 > >Effective c++ 條款17:以獨立語句將newed 物件置入智慧指標

Effective c++ 條款17:以獨立語句將newed 物件置入智慧指標

考慮這樣一個函式和物件:

int priority();
void processWidget(std::tr1::shared_ptr<Widget>pw, int priority);

由於謹記“以物件管理資源”的條款,processWidget決定對其動態分配得來的Widget運用智慧指標。

processWidget(std::tr1::shared_ptr<Widget>(new Widget), priority());

雖然我們在這裡使用”物件管理式資源”,上述呼叫卻可能洩露資源。
編譯器產出一個processWidget呼叫碼之前,必須首先核算即將被傳遞的各個實參。於是在呼叫processWidget之前,編譯器必須建立程式碼,做以下三件事:
呼叫priority;
執行“new Widget”
呼叫tr1::shared_ptr建構函式
c++的編譯器以什麼樣的次序完成這些事情呢?彈性很大。假設priority是第二個執行的,即順序為:
1、執行“new Widget”
2、呼叫priority;
3、呼叫tr1::shared_ptr建構函式
萬一對priority的呼叫導致異常,此時Widget的資源沒有被銷燬,因此會造成資源洩露。
這是因為“在資源被建立”和“資源被轉換為資源管理物件”兩個時間點之間有可能發生異常干擾。
避免這類問題的辦法很簡單:使用分離語句:

std::tr1::shared_ptr<Widget> pw(new Widget);
processWidget(pw, priority());

以上之所以行得通,是因為編譯器對於“跨越語句的各項操作”沒有重新排列的自由(只有在語句內它才擁有那個自由度):執行的順序已經被規定,先執行new Widget,再執行建構函式,再執行priority()。