设计资源管理类时应注意的细节

来源:互联网 发布:免费瓷砖设计软件 编辑:程序博客网 时间:2024/06/09 23:12



在设计自己的资源管理类时,应该注意以下几点:


第一:看自己设计需要,注意Copying行为


(a)如果在你的设计中,不需要进行资源的复制,那么就禁用它(显示声明Copying行为为私有,或直接私有继承Uncopyable),因为按照传统的Copying行为很容易出现资源的重复释放,从而导致程序异常。



错误示例,资源重复释放:

#include <stdio.h>#include <mutex>class Lock{public:explicit Lock(std::mutex* pm)     :mutexPtr(pm) {if(NULL != mutexPtr){mutexPtr->lock();} }~Lock(){if(NULL != mutexPtr){printf("!!!!!!!!!!!!!!!!\n");mutexPtr->unlock();}}private:std::mutex* mutexPtr;};int main(){std::mutex m;// 建立区块使用锁,离开区块自动释放锁{Lock ml1(&m);Lock ml2(ml1);   // 资源重复解锁}return 0;}



正确示例,禁止拷贝,错误控制在编译时期


#include <stdio.h>#include <mutex>class Lock{public:explicit Lock(std::mutex* pm)     :mutexPtr(pm) {if(NULL != mutexPtr){mutexPtr->lock();} }~Lock(){if(NULL != mutexPtr){printf("!!!!!!!!!!!!!!!!\n");mutexPtr->unlock();}}       private:// 禁止copying操作Lock(const Lock&);          Lock operator=(const Lock&);  private:std::mutex* mutexPtr;};int main(){std::mutex m;// 建立区块使用锁,离开区块自动释放锁{Lock ml1(&m);Lock ml2(ml1);   // 无法通过编译}return 0;}






(b)如果你希望设计中允许Copying行为,那么可以对底层资源使用引用计数法(shared_ptr)。


(c)如果你希望设计中允许Copying行为,那么复制资源管理对象时,可以通过进行“深度拷贝”,例如对指针变量进行拷贝时,指针和指向的资源都拷贝一份。


(d)如果你希望设计中允许Copying行为,那么同样可以通过转移底部资源所有权的方式(unique_ptr, auto_ptr)。




备注:
(1) 赋值RAII对象必须一并复制它所管理的资源,所以资源的copying行为决定RAII对象的copying行为。
(2) 普遍而常见的RAII class copying 行为是:抑制copying、施行引用计数法。不过其它行为也可能被实现。


 




第二:看自己设计需要,在资源管理类中提供对原始资源的访问


(1)如果你希望对资源管理类中提供对原始资源的访问,可以如下方式:


(a)提供一个显示转换函数,利用类似get函数获取某个私有方式, 返回对象。


(b)提供一个隐式转换函数, 内部进行转换,类似这种(void implict(long b) ;  int a ;    implict(a) )。


其中,显示转换比较安全,但隐式对客户比较方便。