Effective C++讀書筆記之十四:在資源管理類中小心copying行爲

Item 14:Think carefully about copying behavior in resource-managing classes

條款13導入這樣的觀念:“資源取得時機便是初始化時機”,並以此作爲“資源管理類”的脊柱。然而當一個RAII對象被複制,會發生什麼事?大多數時候你會選擇以下四種可能。

禁止複製:許多時候允許RAII對象被複制並不合理,因爲很少能夠合理擁有“同步化基礎器物”的復件(副本)。如果複製動作對RAII class並不合理,你便應該禁止之。條款6告訴你怎麼做:將copying操作聲明爲private。

對底層資源祭出“引用計數法”:有時候我們希望保有資源,直到它的最後一個使用者(某對象)被銷燬。這種情況下複製RAII對象時,應該將資源的“被引用數”遞增。tr1:shared_ptr便是如此。

tr1:shared_ptr允許指定所謂的“刪除器”,那是一個函數或函數對象,當引用次數爲0時便被調用。刪除器對tr1:shared_ptr構造函數而言是可有可無的第二參數,所以代碼看起來像這樣:

/*假設我們使用C API函數處理類型爲Mutex的互斥器對象,共有lock和unlock函數可用:

 void lock(Mutex* pm);   //鎖定pm所指的互斥器

void unlock(Mutex* pm);   //將互斥器解除鎖定

爲確保絕不會忘記將一個被鎖住的Mutex解鎖,我們建立這樣一個class用來管理機鎖*/

class Lock
{
public:
	explicit Lock(Mutex* pm):mutexPtr(pm,unlock)
	{
		lock(mutexPtr.get());
	}
private:
	std::tr1::shared_ptr<Mutex> mutexPyr;
}

複製底部資源:你需要“資源管理類”的唯一理由是,當你不再需要某個復件時確保它被釋放。在此情況下複製資源管理對象,應該同時也複製其所包覆的資源。也就是說,複製資源管理對象時,進行的是深度拷貝

轉移底部資源的所有權:某些罕見場合下你可能希望確保永遠只有一個RAII對象指向一個未加工資源,即使RAII對象被複制依然如此,此時對象的所有權會從被複制物轉移到目標物。

copying函數可能被編譯器自動創建出來,因此除非編譯器所生版本做了你想要做的事,否則你得自己編寫它們。

請注意:

1.複製RAII對象必須一併複製它所管理的資源,所以資源的copying行爲決定RAII對象的copying行爲。

2.普遍而常見的RAII class copying行爲是:抑制copying、施行引用計數法。不過其他行爲也都可能被實現。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章