effective c++条款14:在资源管理类中小心copying行为

版权声明:转载请注明出处,谢谢!!! https://blog.csdn.net/qhdhnbd110/article/details/83501529

对于智能指针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;
}

这样,对象即使被复制也不会造成什么后果。

猜你喜欢

转载自blog.csdn.net/qhdhnbd110/article/details/83501529