《Effective C++ 中文版 第三版》讀書筆記
** 條款 13:以對象管理資源 **
Toby* CreateToby(); //< 返回指針昂儒,指向 Toby 繼承體系內(nèi)的動態(tài)分配對象。調(diào)用者有責(zé)任刪除它委可。
void t()
{
Toby* pToby = CreateToby();
...
delete pToby;
}
如果 “...” 中的代碼含有 “return”、“goto” 或 “continue” 提早退出,還有可能是“...”區(qū)域內(nèi)拋出異常着倾,若真是這樣拾酝,delete 語句就不會被執(zhí)行。
也許我們自己不會去加這些 “return”卡者,但是代碼不是我們一個人的蒿囤。因此單純的想 “f 總是會執(zhí)行 delete 語句” 是不可能的。
為確保 CreateToby() 返回的資源總是被釋放崇决,我們需要將資源放進(jìn)對象中材诽,這樣,對象的析構(gòu)函數(shù)會幫助我們自動釋放這些資源恒傻。
void t()
{
std::auto_ptr<Toby> pToby(CreateToby());
...
}
這個簡單的例子示范 “以對象管理資源” 的兩個關(guān)鍵想法:
- 獲得資源后立刻放進(jìn)管理對象內(nèi)脸侥,“資源取得時機(jī)便是初始化時機(jī)”(RAII);
- 管理對象運用析構(gòu)函數(shù)確保資源被釋放盈厘。
由于 auto_ptr 被銷毀時會自動刪除它所指之物睁枕,所以一定要注意別讓多個 auto_ptr 同時指向同一個對象。為了預(yù)防這個問題沸手,auto_ptr 有一個性質(zhì):若通過 copy 構(gòu)造函數(shù)或 copy 賦值操作符復(fù)制他們外遇,他們會變成 null,而復(fù)制所得的指針將取得資源的唯一擁有權(quán)契吉!
auto_ptr 的替代方案是“引用計數(shù)型智慧指針”跳仿,即 RCSP。其實質(zhì)也是一個智能指針捐晶,持續(xù)追蹤共有多少對象指向某筆資源菲语,并在無人指向它時自動刪除該資源。RCSP 類似垃圾回收租悄,不同的是 RCSP 無法打破環(huán)狀引用谨究,例如兩個其實已經(jīng)沒被使用的對象彼此互指,因而好像還處在“被使用”狀態(tài)泣棋。
TR1 的 tr1::shared_ptr 就是個 RCSP胶哲,例如:
void t()
{
std::tr1::shared_ptr<Toby> pToby(CreateToby());
...
}
這段代碼看起來幾乎和使用 auto_ptr 的代碼相同,但是 shared_ptr 的復(fù)制行為正常多了潭辈。
請記籽煊臁:
- 為了防止資源泄漏,請使用 RAII 對象把敢,它們在構(gòu)造函數(shù)中獲得資源并在析構(gòu)函數(shù)中釋放資源寄摆。
- 兩個常被使用的 RAII class 分別是 tr1::shared_ptr 和 auto_ptr。前者通常是較佳選擇修赞,因為其 copy 行為比較直觀婶恼。若選擇 auto_ptr桑阶,復(fù)制動作會使它(被復(fù)制物)指向 null。