Item 14-在資源管理中小心的copying行為(Think carefully about copying behavior in resource-managing classes)
auto_ptr和trl::shared_ptr表現在heap_based資源上,然而並非所有資源都是heap_based,這樣我們就需要建立自己的資源管理類。
例如:假設我們使用C API(Application Programming Interface)函數處理類型為Mutex的互斥器對象(mutex objects),共有lock和unlock兩函數可用:
void lock(Mutex* pm); //鎖定pm所指的互斥器 void unlock(Mutex* pm); //將互斥器解除鎖定
為確保絕不忘記將一個被鎖住的Mutex解鎖,你可能會希望建立一個class用來管理機鎖。這樣的class的基本結構由RAII守則支配,也就是"資源在構造期間獲得,在析構期間釋放"。
class Lock { public: explicit Lock(Mutex* pm):mutexPtr(pm){Lock(mutexPtr);} //獲得資源 ~Lock(){unlock(mutexPtr);} //釋放資源 private: Mutex* mutexPtr; };客戶對Lock的用法符合RAII方式:
Mutex m; //定義你需要的互斥器 ... { //建立一個區塊用來定義critical section Lock ml(&m); //鎖定互斥器 ... //執行critical section內的操作 } //在區塊最末尾,自動解除互斥器鎖定Note:critical section臨界區。不論是硬件臨界資源,還是軟件臨界資源,多個線程必須互斥地對它進行訪問。每個線程中訪問臨界資源的那段代碼成為臨界區。
如果Lock對象被復制;
Lock ml1(&m) //鎖定m Lock ml2(ml1) //將ml1復制到ml2身上。?怎麼辦
1、禁止復制
2、將底層資源使用"引用計數法"(reference-count)
3、復制底部資源
4、轉移底部資源的擁有權
請記住:
復制RAII對象必須一並復制它所管理的資源,所以資源的copying行為決定RAII對象的copying行為。
普遍而常見的RAII class copying行為是:抑制copying、使用引用計數法(reference counting)。不過其他行為也都可能被實現。