这里我就直接贴代码然后进行说明了。
拷贝型资源管理对象
对于普适性的资源,比如string、vector、array等资源,我们通常采用拷贝的方式进行资源的赋值操作
下面是这种资源管理对象的基本构造:
template<typename T>
class Data
{
private:
T* pointer;
public:
Data(const Data& d) :pointer(new T(*(d.pointer))) {};
Data() :pointer(NULL) {};
Data(T* p) :pointer(p)
{
};
~Data()
{
delete pointer;
}
T& operator*() { return *(this->pointer); }
Data& operator =(Data rhs)
{
delete pointer;
pointer = new T(*(rhs.pointer));
return *this;
}
};
然后我们测试一下:
void test()
{
Data<int> p1(new int(3));
Data<int>p2 = p1;
*p2 = 5;
cout << *p1 << " "<<*p2<<endl;//输出 3 5
}
可以看到,当这种资源管理对象发生赋值的时候,就会产生新的资源副本,然后两个对象的资源就此隔离没有任何关系了。一个对象资源的改变不会影响另一个资源对象管理的资源
控制权转移的资源管理对象
这种控制权交换的情况有很多,比如mutex的锁等等临界资源,也就是只能被一个线程使用的资源,这样的资源不能进行拷贝,只能进行支配权的转移
大致构造如下:
template<typename T>
class Data
{
private:
T* pointer;
public:
Data(Data& d):pointer( d.pointer)
{
d.pointer = NULL;
};
Data() :pointer(NULL) {};
Data(T* p=NULL) :pointer(p)
{
};
~Data()
{
delete pointer;
}
T& operator*() { return *(this->pointer); }
Data& operator =(Data rhs)
{
delete pointer;
pointer = rhs.pointer;
rhs.pointer = NULL;
return *this;
}
};
当管理这种资源的对象进行赋值操作或则拷贝构造的时候,就会取消源资源对象对资源的的控制权,然后由新的资源管理对象对资源进行独自的管理
只有一个本体(但能被多个对象访问)的资源
还有一种资源,这种资源产生之后可以被大家共享。每个共享者实际上使用的都是同一个资源副本,当其中一个使用者被析构了不一定会释放内存,而是所有使用者都被销毁了,才会释放这块资源占据的内存。我们就添加一个计数器变量来统计使用者数量。
下面就是一个简略的计数型资源管理对象的设计:
template<typename T>
class Data
{
private:
size_t* count;
T* pointer;
public:
Data(const Data& d) :pointer(d.pointer), count(d.count)
{
++(*count);
}
Data() :pointer(NULL),count(NULL) {};
Data(T* p = NULL) :pointer(p), count(new size_t(1)) {};
~Data()
{
cout << "~Data" << endl;
if (--(*count) == 0)
{
delete pointer;
delete count;
cout << "无人访问,删除共享资源" << endl;
}
}
T& operator*() { return *(this->pointer); }
size_t user() { return *count; };
Data& operator =(Data rhs)
{
pointer = rhs.pointer;
count = rhs.count;
*(this->count) += 1;
return *this;
}
};
由于在赋值和拷贝的时候要对这个资源的所有计数器都进行更新,所以使用了
size* count
(一个指针对象)来进行实时同步。并且提供user()
来查看当前有多少使用者。
一个测试代码:
void test()
{
Data<int> p1(new int(3));
Data<int>p2 = p1;
*p2 = 5;
cout << *p1 << " " << *p2 << endl;
cout << "user: " << p1.user() << endl;
}
结果如下:
5 5
user: 2
~Data
~Data
无人访问,删除共享资源
可以看到,是很符合我们预期的,所有资源都可以很好的被分到不同的类别中去,然后进行不同类型资源的管理。保证资源的不同使用方法都能得到安全释放。