Effective-cpp-#14

Think carefully about copying behavior in resource-managing classes

动机

这是接上一个条款讲述的,当我们用一个对象去管理资源类的时候,我们需要注意该资源是否应该被复制。比如,一个互斥锁,是不应该拥有副本的。因此我们需要某些方法来保证管理这个锁的对象不会被复制,或者我们希望RAII对象被复制时追踪它的使用。

管理方法

  • 禁止复制

使用条款6的方法,即继承一个uncopyable的类。具体可以看条款6

1
2
3
4
class Lock: private Uncopyable{
public:
...
};
  • 对底层资源进行“reference-count”(引用计数)

这种管理方法是因为我们希望保有资源,知道最后一个使用者被销毁时,才销毁资源。这种缘由恰好可以用shared_ptr来管理。但有一个问题是,假如我们希望管理的资源是一个互斥锁,那么我们并不希望该资源在引用计数为0时被销毁,而是解锁。

这时就需要用到删除器了。

1
2
3
4
5
6
7
8
class Lock{//这个类可以不析构,因为非静态变量在对象销毁时被析构函数收回
public:
explicit Lock(Mutex* pm):mutexPtr(pm, unlock){//在引用计数为0时自动调用单参数函数unlock()
lock(mutexPtr.get());
}
private:
std::trl::shared_ptr<Mutex> mutexPtr;
}
  • 转移底部资源的控制权

这里可以使用先前提及的auto_ptr<>

建议

  • 复制RAII对象时,必须一并复制它所管理的资源
  • RAII class copying的行为通常有:禁止复制,使用引用计数,转移资源的控制