Effective c++学习笔记条款14:在资源管理类型中小心copying行为

Think carefully about copying behavior in resource-managing classes

    在上一款中我们谈到,用资源管理类来管理动态分配的资源及如何运用auto_ptr和tr1::share_ptr管理
即使有了智能指针auto_ptr、引用计数型智能指针shared_ptr,有时难免还是需要实现自己的资源管理类型。假设Mutex类型通过lock和unlock两组函数进行互斥器的锁定和解锁,可能我们希望和auto_ptr一样的行为,在某个智能类型析构时主动调用unlock进行解锁。比如下面的代码:

#include "stdafx.h"
#include <stdlib.h>


class Mutex;
class auto_lock;

void lock(Mutex *pM) { }
void unlock(Mutex *pM) { }

class Mutex { };

class auto_lock {
public:
explicit auto_lock(Mutex *pM) 
: _mutexPtr(pM) { 
lock(pM);
}
~auto_lock() { 
unlock(_mutexPtr);
}
private:
Mutex *_mutexPtr;
};

int _tmain(int argc, _TCHAR* argv[]) {
Mutex m;
auto_lock lockM(&m);
auto_lock lockM2(lockM);
system("pause");
return 0;
}


 

当lockM2使用copy构造函数时,应该怎样做才是合理的?
一种方式是禁止复制,即将copy构造函数声明为private来阻止这种多份引用的行为。在第六条款中有提到的做法,派生于noncopyable类型。

class noncopyable {
protected:
noncopyable() { }
~noncopyable() { }
private:
noncopyable(const noncopyable&);
noncopyable& operator=(const noncopyable&);
};

class auto_lock : private noncopyable {
public:
explicit auto_lock(Mutex *pM) 
: _mutexPtr(pM) { 
lock(pM);
}
~auto_lock() { 
unlock(_mutexPtr);
}
private:
Mutex *_mutexPtr;
};


 

另一种方法是使用资源引用计数法,直到最后一个使用者被销毁的时候,才进行真正意义上的销毁。在内部不再使用原类型的指针,而是改用tr1库的shared_ptr。shared_ptr不仅本身可以自行释放某个类型,同时它可以接受一个函数指针,自定义用户的删除方式。在线程锁的时候,我们只是希望解锁并不是删除Mutex。

class auto_lock {
public:
explicit auto_lock(Mutex *pM) 
: _mutexPtr(pM, unlock) { 
lock(_mutexPtr.get());
}
private:
shared_ptr<Mutex> _mutexPtr;
};


请记住:
    ◆ 复制RAII对象必须一并复制它所管理的资源,所以资源的copying行为决定RAII对象的copying行为.
    ◆ 普遍而常见的RAII class copying行为是:抑制copying、施行引用计数法.不过其它行为也都可能被实现.

你可能感兴趣的:(C++,System,Class,behavior,RAII)