effective c++:资源管理相关

以对象管理资源

许多资源被动态分配与heap内而后被用于单一区块或函数内。他们应该在控制流离开那个区开或函数时被释放。

class Investment{...};						//投资类型继承体系中的root class
Investment* createInvestment();    				//返回指针,指向Investment继承体系内的动态分配对象,调用者有责任删除它
void f(){
  std::shared_ptr<Investment> pInv(createInvestment());	//调用factory函数
   ...                  					//经由shared_ptr的析构函数自动删除pInv
}

获得资源后立刻放进管理对象内。以对象管理资源的观念常被称为资源获取时机便是初始化时机(Resource Acquisition Is Initialization;RAII)

管理对象运用析构函数确保资源被释放。


然而并非所有资源都是heap-based,对那种资源而言,像auto_ptr和shared_ptr这样的智能指针往往不适合作为资源管理者。

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

void lock(Mutex* pm);					//锁定pm所指互斥器
void unlock(Mutex* pm);					//将互斥器解除锁定

建立一个class用来管理机锁,这样的class基本结构由RAII守则支配,也就是”资源在构造期间获得,在析构期间释放”:

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

客户对Lock的用法符合RAII方式:

Mutex m;					//定义你需要的互斥器
...
{						//建立一个区块定义critical section
  Lock m1(&m);			        //锁定互斥器
  ...						//执行critical section内的操作
}						//在区块末尾,自动解除互斥器锁定

Lock ml1(&m);					//锁定m
Lock ml2(ml1);					//将ml1复制到ml2身上,会发生什么?

面对“一个RAII对象被复制会发生什么?”大多数时候会有两种选择:

1)禁止复制

class Uncopyable{
protected:					//允许derived对象构造和析构
  Uncopyable(){}
  ~Uncopyable(){}
private:					//不予实现
  Uncopyable(const Uncopyable&);		//阻止copying
  Uncopyable& operator=(const Uncopyable&);
};
class Lock:private Uncopyable{
public:
  ...						//如前
}

2)对底层资源基础“引用计数法”

tr1::shared_ptr允许指定所谓的“删除器”,那是一个函数或函数对象,当引用次数为0时便被调用。

class Lock{
public:
  explicit Lock(Mutex* pm)
    : mutexPtr(pm,unlock)					//以unlock函数作为删除器
{
  lock(mutexPtr.get());
}
private:
  std::tr1::shared_ptr<Mutex>mutexPtr;
};






猜你喜欢

转载自blog.csdn.net/duangyhn/article/details/76713884