1. 程式人生 > >effective c++條款14:在資源管理類中小心copying行為

effective c++條款14:在資源管理類中小心copying行為

對於智慧指標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;
}

這樣,物件即使被複制也不會造成什麼後果。