effective c++條款14:在資源管理類中小心copying行為
阿新 • • 發佈:2018-11-02
對於智慧指標auto_ptr和tr1::shared_ptr,它們在作用域結束時會將所指內容自動刪除。
然而對於某些系統資源,比如互斥鎖(muxex)等並不是在堆中申請的,是長期存在的,只能去釋放,不能將其刪除,這樣,我們就不能用智慧指標去管理它,資源管理類是個好的選擇。
考慮用下面的類去管理Mutex:
class ManageMutex { private: HANDLE MyMutex; public: explicit ManageMutex(HANDLE SomeMutex):MyMutex(SomeMutex) { } ~ManageMutex() { ReleaseMutex(MyMutex); } };
如果你的資源管理類被copy,那麼就會出現兩個物件管理一個Mutex資源,如果其中一個作用域結束,那麼資源就會隨之釋放,那麼另一個物件的資源也就被釋放掉了,為了避免其帶來的後果,我們可以:
1. 禁止複製(詳見條款6)
class UnCopy { public: UnCopy(){} ~UnCopy(){} private: UnCopy(const UnCopy &){} UnCopy &operator=(const UnCopy &){} } class ManageMutex:private UnCopy { private: HANDLE MyMutex; public: explicit ManageMutex(HANDLE SomeMutex):MyMutex(SomeMutex) { } ~ManageMutex() { ReleaseMutex(MyMutex); } };
2. 利用std::tr1::shared_ptr指標
tr1::shared_ptr可以對所管理資源進行計數,也就是說如果存在多個tr1::shared_ptr管理同一個資源,那麼只有當最後一個管理者作用域結束,資源才會被刪除。
雖然tr1::shared_ptr指標會刪除所指資源,但那只是預設操作,其建構函式擁有兩個引數:一個是所管理資源的指標(或控制代碼),另一個是一個預設的刪除呼叫,預設值為所管理資源的解構函式,如果我們自行傳遞一個ReleaseMutex函式,就會替換這個預設值:
#include <iostream> #include <Windows.h> #include <memory> using namespace std; class ManageMutex { private: std::tr1::shared_ptr<HANDLE> MyMutex; public: ManageMutex(HANDLE *SomeMutex):MyMutex(SomeMutex, ReleaseMutex){} }; int main(void) { HANDLE hMutex = CreateMutex(NULL, 0, NULL); ManageMutex ManagerA(&hMutex); return 0; }
這樣,物件即使被複制也不會造成什麼後果。