[Effective C++ --014]在资源管理类中小心copying行为
第一节 <背景>
条款13中讲到“资源取得的时机便是初始化时机”并由此引出“以对象管理资源”的概念。通常情况下使用std中的auto_ptr(智能指针)和tr1::shared_ptr(引数智能指针)作为管理资源的对象。
事实上,这种管理方法十分有效。但是,auto_ptr和tr1::shared_ptr只能管理基于堆(heap-based)的资源,而非heap-based的资源却往往不适合。
因此,有的时候你需要建立自己的资源管理类。本文介绍的内容是在你建立自己的资源管理类时应该注意的事项。
第二节 <正文>
我们知道在C API中处理Mutex的互斥对象,有lock何unlock两个函数可用:
void lock(Mutex* pm); // 锁定pm指向的互斥量void unlock(Mutex* pm); // pm指向的互斥量解锁
假设我们写了Lock类来管理锁。
class Mutex{ public:Mutex():Count(0){} public:int Count; }; void lock(Mutex* pm){pm->Count++;} void unlock(Mutex* pm){pm->Count--;} class Lock { public:explicit Lock(Mutex* pm):mutexPtr(pm){lock(mutexPtr);} // 将mutexPtr指向的互斥变量加锁~Lock(){unlock(mutexPtr);} // 将mutexPtr指向的互斥变量解锁 private :Mutex * mutexPtr; };
上面代码满足RAII(Resource Acquisition is Initialization)原则即,资源在获取时既是初始化时,失去时既是清理时。
想象下面的场景时,程序的输出结果是什么。
1 Mutex m; 2 cout << "Mutex is " << m.Count << endl; 3 Lock m1(&m); 4 cout << "Mutex is " << m.Count << endl; 5 Lock m2(m1); 6 cout << "Mutex is " << m.Count << endl; 7 m1.~Lock(); 8 cout << "Mutex is " << m.Count << endl;
输出结果为:
Mutex is 0 Mutex is 1 Mutex is 1 Mutex is 0
这是为什么呢?前两个0和1输出无可厚非,第三个的输出为拿m1作为实例对象去赋值给m2,操作对象为m1,不会直接影响m;第四个互斥量m的管理者m1被销毁了,那么m也就被解锁了。
在上面的例子中,m的值不断被变更,显然,这种资源的管理的方式是不合理的。
可能的解决方法:
1.禁止复制。禁止复制的做法具体的可参照条款6的说明。
class UnCopyable { public:UnCopyable(){} private:UnCopyable(const UnCopyable& ths) {} }; class Lock:private UnCopyable {... }
2.使用引用计数智能指针:tr1::shared_ptr。
从条款13我们已经知道引用计数智能指针会跟踪使用该资源的所有对象数,计数为0时,资源会被删除。注意,这里删除互斥量m不是我们所期待的,我们期待是解锁互斥量
幸运的是tr1::shared_ptr允许自定义所谓的“删除”动作,该动作是在计数为0时执行的。于是类Lock可以是下面的样子。
class Lock { public:explicit Lock(Mutex* pm):mutexPtr(pm,unlock){lock(mutexPtr.get());} // 将mutexPtr指向的互斥变量加锁 private :shared_ptr<Mutex> mutexPtr; };
有没有发觉貌似少了点东西?对,析构函数没有了。因为share_ptr会帮你完成这一工作。
3.复制管理对象时也复制所管理的资源。
请回头想一个问题:为什么需要自己的资源管理类?那么,可能的理由是当不需要某个资源时,资源能被正常释放(删除,其他动作)。资源存在多个复件并不可怕,可怕的是复件在该销毁的时候却没有销毁。也就是,管理对象与所管理的资源要一一对应。为了保证这种对应关系,在复制管理对象时也复制所管理的资源。
4.转移资源的管理权。
在某些特殊场合下,你可能希望资源只被一个对象拥有,也就是管理对象在copying时要进行资源所有权的转移。从条款13中讲到的auto_ptr可以完美的实现这个需求。
■总结
1.复制管理对象时,请一并复制对象所管理的资源,资源的copy行为决定了管理对象的copy行为
2.普遍的RAII class的copy行为是抑制复制,使用引用计数
转载于:https://www.cnblogs.com/hustcser/p/4103527.html
[Effective C++ --014]在资源管理类中小心copying行为相关推荐
- [Effective C++]条款14:在资源管理类中小心copying行为
复制 RAII 对象必须一并复制它所管理的资源,所以资源的 copying 行为决定 RAII 对象的 copying 行为 普遍而常见的 RAII class copying 行为是:阻止 copy ...
- Effective Java之在公有类中使用访问方法而非公有域(十四)
1.对于公有类来说,如果类可以在它所在的包的外部进行访问,就提供访问方法,以保留将来改变该类的内部表示法的灵活性. 如果公有域暴露了他的数据域,要想在将来改变它的内部表示法是不可能的,因为公有类的客户 ...
- Effective C++ 3nd笔记——资源管理
Effective C++ 3nd---资源管理 以对象管理资源 简单来说就是要用类来管理资源,最好使用C++11新标准提供的几种智能指针 请记住: 为防止资源泄漏,请使用RAII对象,他们在构造函数 ...
- 《Effective C++ 3th》——资源管理
文章目录 资源如何释放? 注意资源的唯一性 由使用智能指针引出的问题 以对象管理资源 在资源管理类中小心coping行为 在资源管理类中提供对原始资源的访问 成对使用new和delete时要采取相同形 ...
- [.NET] 《Effective C#》快速笔记 - C# 中的动态编程
<Effective C#>快速笔记 - C# 中的动态编程 静态类型和动态类型各有所长,静态类型能够让编译器帮你找出更多的错误,因为编译器能够在编译时进行大部分的检查工作.C# 是一种静 ...
- 扩展Visual Studio 2010服务器资源管理器中的SharePoint结点
Visual Studio 2010最大的卖点就是可扩展性.这样就可以借助.NET社区的力量基于VS构建出许多有用的工具.本文中我们将展示如何扩展VS2010的服务器资源管理器,在其中的SharePo ...
- 为什么要在Java的Serializable类中使用SerialVersionUID
序列化和SerialVersionUID始终是许多Java开发人员的难题. 我经常会看到类似此SerialVersionUID的问题,或者如果不在我的Serializable类中声明SerialVer ...
- java枚举类中字段有没有必要加final____枚举类字段 Field ‘xxx‘ may be ‘final‘
java枚举类中字段有没有必要加final 今天在写一个系统统一返回码的枚举类时候,突然想到一个问题,当不小心手抖给枚举类自动生成了set方法,而恰巧在用的地方不小心用了set方法,从而修改了code ...
- C++类中的枚举类型
在看effective c++的时候,其中第二条边指出.尽量使用const ,enum代替define.在写程序的时候,需要入参为设备类型,第一反应是枚举一个设备类型,并以名字命名.但是有一个问题挺困 ...
最新文章
- python对象编程例子-python面向对象编程练习
- java订单编号生产代码,java 订单编号 生成器,可用于生产环境
- 如何处理SAP Fiori gateway service使用过程中遇到的404 error
- Anaconda管理多版本的python环境
- angularjs中按回车事件_在AutoCAD中巧用空格键或回车键,制图效率高
- IntelliJ IDEA 运行你的第一个Java应用程序
- 软件_避免用chrome进行网站配置调试[博]
- javascript 基础之事件(event)-------1
- 我从不劝退,我就是退。
- 5.3 数据通路-专用通路
- IE8升级到IE11 F12报错的解决方案
- 科技热点周刊|ClickHouse 融资 2.5 亿美元、个人信息保护法正式实施、Facebook 改名 Meta
- 3GPP中的各种缩写
- 【网络工程】计算机网络专业术语概论全面整理
- Ubuntu设置1080分辨率
- 惊闻母校徐兵老师英年早逝
- 华为云早报 谷歌亚马逊抢食美军100亿美元云计划
- 英语学习单词篇(12)
- 电驴提示“该内容尚未提供权利证明,无法提供下载”之解决办法详解
- php多张图合成一张图,PHP中多张图片合成一张图片例子
热门文章
- wps2019去弹窗广告和屏保
- Direct2D学习教程(一)
- 全球及中国企业级多级单元(MLC)闪存行业研究及十四五规划分析报告
- 服务器终端授权,终端服务器许可 - Windows Server | Microsoft Docs
- Protel99 SE进行射频电路PCB设计的流程【转】
- 服务端发现2t3ik.p进程占CPU过高。2t3ik ddgs.3011
- 【USB接口】USB-Type-A B C 、Micro-USB、Mini-USB接口描述
- 在Word中隐藏文字
- 当咖啡师,开咖啡店,要学哪些东西
- 502 bad gateway是什么意思?502 bad gateway怎么解决!