Effective C++条款14:在资源管理类中小心Copying行为

之前条款13中说到,用对象来管理资源,然而并非所有资源都是基于堆,对于这种资源,智能指针往往不适合作为资源掌管者。
这个时候,就需要建立自己的资源管理类。

假如我们使用C API函数处理类型为Mutex的互斥对象,共有lock和unlock两个函数可用:

void lock(Mutex * pm);
void unlock(Mutex * pm);

为了确保不会忘记将一个锁住的Mutex解锁,你可能会希望建立一个类来管理。这样的类基本和条款13说的差不多,资源在构造期间获得,在析构期间释放:

class lock
{
public:
	explicit lock(Mutex * pm) : mutexPtr(pm)
	{lock(mutexPtr);}
	~lock(){unlock(mutexPtr);}//释放资源
private:
	Mutex * mutexPtr;
}

这看上去没问题,但如果Lock对象被复制会发生什么事情?

lock m1(&m);
lock m2(m1);

当一个RAII对象被复制,会发生什么事情?大多数时候你可能会选择以下两种可能:
1.禁止复制,使用条款6的做法。
2.对底层资源使用引用计数法,比如使用shared_prt,这种情况下复制RAII对象时,资源的被引用数递增.

然而如果你使用了shared_prt,它在引用次数为0的时候删除其管理的资源。那不是我们想要的行为,我们想要做的释放动作是解除锁定而不是删除。

幸好的是shared_prt允许指定删除器,当引用次数为0时删除器便被调用。
代码可以这样写:

class lock
{
public:
	explicit lock(Mutex * pm) : mutexPtr(pm, unlock)
	{lock(mutexPtr.get());}
	~lock(){unlock(mutexPtr);}//释放资源
private:
	std::shared_prt<Mutex>mutexPtr;
}

注意:lock 类不在声明析构函数,类的析构函数会自动调用非静态成员变量的析构函数,而mutexPtr会在互斥器的引用次数为0时自动调用shared_ptr的删除器。

总结:
1.复制RAII对象必须一并复制它所管理的资源。
2.普遍而场景的RAII class copying行为是:抑制Copying、使用引用计数法。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值