条款14:在资源管理中心小心copy行为之重难点

不仅仅动态分配的内存是资源,像文件描述器,互斥锁,数据库连接,以及网络sockets等也是资源,如果不及时关闭,也会造成资源浪费。

重点1:建立自己的资源管理类

如果是heap-based资源,则可以用auto_ptr或shared_ptr管理资源。然而并非所有资源都是heap-based,这样,就需要建立自己的资源管理类。

以互斥锁为例,为确保不会忘记将一个被锁住的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;
...
{
  Lock m1(&m);	
  ...
}
难点1:RAII class copying行为
如果上面Lock对象被复制,会发生什么事?

Lock m11(&m); 	       //锁定m                                                  
Lock m12(&m11);	       //将m11复制到m12身上 

这是一个一般化问题的特定例子:当一个RAII 对象被复制,会发生什么事?大多时候,选择下面两种可能:

1)禁止复制。

class Uncopyable
{
protected:    	      	    //允许继承对象构造和析构                            
  Uncopyable(){}
  ~Uncopyable(){}
private:
  Uncopyable(const Uncopyable &);     //但阻止copy                              
  Uncopyable &operator=(const Uncopyable&);
};
<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">为阻止Lock对象被复制,我们唯一需要做的就是继承Uncopyable:</span>
<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"></span><pre name="code" class="cpp">class Lock:private Uncopyable
{
public:
  ...
};


 2)对底层资源祭出“引用计数法”。 

有时候我们希望保有资源,直到它的最后一个使用者被销毁。这个时候使用tr1::shared_ptr来引用计数。但是tr1::shared_ptr的缺省行为是“当引用次数为0时”删除其所指物,那不是我们的行为。当我们用上Mutex,我们想要做的释放动作是解锁而不是删除。

这可以给tr1::shared_ptr指定删除器来实现:

class Lock
{
public:
  explicit Lock(Mutex* pm):mutexPtr(pm,unlock)	  //unlock为指定的删除器        
  {
    lock(mutexPtr.get());     	      	      	  //get为显示转换函数           
  }
private:
  std::tr1::shared_ptr<Mutex> mutexPtr;	      	  //使用shared_ptr代替原始指针  
};
注意1:shared_ptr有两个参数,第一个是类型,第二个指定删除器,一般是函数,第二个参数可以省略,表示默认是删除对象。

注意2:本例的Lock class不再声明析构函数。class析构函数会自动调用其non-static成员变量的析构函数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值