C++程序中最常用的资源包括动态分配的内存,文件描述器,互斥锁,数据库连接,网络socket等等。不论哪种资源,重要的是,当你不再使用他时,必须将他归还给系统。

一个很好的做法是以对象管理资源。把资源放进对象内,我们便可依赖C++的析构函数自动调用机制确保资源被释放,这样便不会发生资源泄露的问题。一个实现的方法是,以智能指针封装资源,由于atuo_ptr缺陷太多,已经基本被废弃,建议使用shared_ptr。下面看一个使用shared_ptr的具体实现

    1. void f()
      1. {
        1. shared_ptr<Investment> pInv(createInvestment());//工厂函数返回的对象初始化资源,再用shared_ptr封装他
          1. }

        shared_ptr的一个特性是其提供了引用计数,每当其管理对象被指向便会+1,在无人指向它时自动删除该资源,并且支持copy操作。因为可以很方便的通过它进行内存管理,不用担心资源泄露。

        在资源管理类中小心copying行为

        一般情况下,对资源的复制行为是不会允许的,比如互斥锁,你不会想要把一个互斥器对象复制的,对吧?所以如果你的资源对象不适合被复制,你应该禁止复制这种行为:把copying操作声明为private,然后继承它,就像下面这样

          1. class Lock:private Uncopyable
            1. {
              1. ...
                1. };

              或者如果你确实有需求复制资源,例如你非得复制互斥器,那就使用前面介绍的shared_ptr吧,但是shared_ptr有一个不幸的特性,当引用次数为0时删除其所指物,不过类似于C++标准库里的其他部件,shared_ptr允许你定制自己的删除器,shared_ptr有一个重载类型接受第二个参数。

                1. Class Lock
                  1. {
                    1. public:
                      1. explicit Lock(Mutex* pm):mutexPtr(pm,unlock)//第二个参数指定引用计数为0时的行为,即是unlock
                        1. {
                          1. lock(mutexPtr.get());//mutexPtr.get()返回mutexPtr管理对象的原生类型
                            1. }
                              1. private:
                                1. shoread_ptr<Mutex> mutexPtr;
                                  1. };

                                在资源管理类中提供对原始资源的访问也是一个重要的功能。

                                对于share_ptr,它提供了get()成员函数,用来执行显式转换,返回智能指针内部的原始指针

                                对与我们自定义资源管理类,有两种方式提供对原始资源的访问:显式转换函数和隐式转换函数

                                  1. //假设我们有这样一个类
                                    1. class Font
                                      1. {
                                        1. public:
                                          1. explicit Font(FontHandle fg):f(fh){}
                                            1. private:
                                              1. FontHandle f;
                                                1. };

                                              其显式转换函数形式为

                                              1. FontHanld get() const { return f; }

                                              其隐式转换函数形式为

                                              1. operateor FontHandle() const { return f; }

                                              这两种形式各有好处,隐式转换的好处是比较自然,但是会增加错误发生机会,例如我们本想得到一个Font,结果却意外得到FontHandle

                                                1. Font f1(getFont());
                                                  1. FontHandle f2=f1;//这里会将Font转型为FontHandle,假如这不是你想要的呢?这个错误很隐蔽

                                                在使用智能指针时会发生一个问题,如果有一个函数是以下形式:

                                                1. process( shared_ptr<Investment> (new Investment),priority );

                                                这条语句有三个动作:

                                                调用unlock,执行new Investment,调用shared_ptr构造函数。我们知道,new Investment动作一定在shared_ptr构造函数之前,另外C++对构造函数内动作的次序是无定义的,如果unlock动作发生在第二顺位,并且如果它的调用导致异常,此时new Investment返回的指针会遗失,引发资源泄露。对此,解决方法是先建立好智能指针。

                                                  1. shared_ptr<Investment> p(new Investment);
                                                    1. process(p,priority);

                                                  总结起来便是,以独立语句将newed对象置入智能指针。

                                                  《Effective C++》读书笔记 资源管理的更多相关文章

                                                  1. Effective STL 读书笔记

                                                    Effective STL 读书笔记 标签(空格分隔): 未分类 慎重选择容器类型 标准STL序列容器: vector.string.deque和list(双向列表). 标准STL管理容器: set. ...

                                                  2. Effective STL读书笔记

                                                    Effective STL 读书笔记 本篇文字用于总结在阅读<Effective STL>时的笔记心得,只记录书上描写的,但自己尚未熟练掌握的知识点,不记录通用.常识类的知识点. STL按 ...

                                                  3. effective c++读书笔记(一)

                                                    很早之前就听过这本书,找工作之前读一读.看了几页,个人感觉实在是生涩难懂,非常不符合中国人的思维方式.之前也有博主做过笔记,我来补充一些自己的理解. 我看有人记了笔记,还不错:http://www.3 ...

                                                  4. Effective Java读书笔记完结啦

                                                    Effective Java是一本经典的书, 很实用的Java进阶读物, 提供了各个方面的best practices. 最近终于做完了Effective Java的读书笔记, 发布出来与大家共享. ...

                                                  5. Effective java读书笔记

                                                    2015年进步很小,看的书也不是很多,感觉自己都要废了,2016是沉淀的一年,在这一年中要不断学习.看书,努力提升自己 计在16年要看12本书,主要涉及java基础.Spring研究.java并发.J ...

                                                  6. Effective C++读书笔记(转)

                                                    第一部分 让自己习惯C++ 条款01:视C++为一个语言联邦 一.要点 ■ c++高效编程守则视状况而变化,取决于你使用c++的哪一部分. 二.扩展 将c++视为一个由相关语言组成的联邦而非单一语言会 ...

                                                  7. Effective Objective-C 读书笔记

                                                    一本不错的书,给出了52条建议来优化程序的性能,对初学者有不错的指导作用,但是对高级阶段的程序员可能帮助不是很大.这里贴出部分笔记: 第2条: 使用#improt导入头文件会把头文件的内容全部暴露到目 ...

                                                  8. Effective C++ 读书笔记(13-32)

                                                    条款一十三:以对象管理资源 1.把资源放进对象内,我们便可依赖C++的“析构函数自动调用机制“确保资源被释放. 2.auto_ptr是个”类指针对象“,也就是所谓”智能指针“,其析构函数自动对其所指对 ...

                                                  9. 【Effective C++读书笔记】序

                                                    C++ 是一个难学易用的语言! [C++为什么难学?] C++的难学,不仅在其广博的语法,以及语法背后的语义,以及语义背后的深层思维,以及深层思维背后的对象模型: C++的难学还在于它提供了四种不同而 ...

                                                  随机推荐

                                                  1. OpenFlow, SDN, and NFV

                                                    OpenFlow An open standard to innovative protocols in production networks provides a standardized hoo ...

                                                  2. Spring Bean自动注册的实现方案

                                                    这里Spring管理的Bean,可以认为是一个个的Service,每个Service都是一个服务接口 自动注册Service的好处: 1.根据指定的name/id获取对应的Service,实现简单工厂 ...

                                                  3. jquery固定位置浮动

                                                    示例: <!DOCTYPE html> <html> <head> <title>test page</title> <script ...

                                                  4. Java中集合随笔

                                                    先上一张图:关于collection接口的 一.Collection中的常用功能: boolean add(Object e): 向集合中添加元素void clear():清空集合中所有元素boole ...

                                                  5. Sftp搭建与配置参考

                                                    Sftp搭建与配置参考 1. 介绍 sftp是Secure File Transfer Protocol的缩写,安全文件传送协议.可以为传输文件提供一种安全的加密方法.sftp 与 ftp 有着几乎一 ...

                                                  6. JavaScript高级程序设计(复制变量值、传递参数)

                                                    复制变量值 一个变量向另一个变量复制基本类型值和引用类型值时,是存在不同的. 一个变量向另一个变量复制基本类型的值,会在变量的对象上创建一个新值,然后把该值复制到为新变量分配的位置上. var num ...

                                                  7. es6 Set 和Map 数据结构

                                                    ES6提供了新的数据结构Set,它类似于数组,但是成员的值都是唯一的,没有重复的值. Set 本身是一个数据结构,用来生成Set 数据结构. const s = new Set(); [2,3,5,4 ...

                                                  8. C++分享笔记:扑克牌的洗牌发牌游戏设计

                                                    笔者在大学二年级期间,做过的一次C++程序设计:扑克牌的洗牌发牌游戏.具体内容是:除去大王和小王,将52张扑克牌洗牌,并发出5张牌.然后判断这5张牌中有几张相同大小的牌,是否是一条链,有几个同花等. ...

                                                  9. @Component注解、@Service注解、@Repository注解、@Controller注解区别

                                                    --------------------------------------------------------------------------------------------------- ...

                                                  10. 关于Quartz 2D绘图的简单使用

                                                    Quartz 2D是一个二维图形绘制引擎,支持iOS环境和Mac OS X环境,Quartz 2D的API可以实现许多功能,如:基于路径的绘图.透明度.阴影.颜色管理.反锯齿.PDF文档生成和PDF元 ...