三、资源管理

      资源就是一旦你使用了它,将来不用的时候必须归还系统。C++中最常用的资源就是动态内存分配。其实,资源还有 文件描述符、互斥器、图形界面中的字形、画刷、数据库连接、socket等。

1、        以对象管理资源

      void f()

{

    investment *plv = createInvestment();

    //这里存在很多不定因素,可能造成下面语句无法执行,这就存在资源泄露的可能。

    delete plv;

}

     这里我们把资源放进一个对象里面,然后依赖C++本身的对象里面的析构函数帮我们确保资源被释放。这里用到auto_ptr来解决。这是一个类指针对象,也就是所谓的智能指针。其析构函数自动调用delete。

    std::auto_ptr<Investment> pInv1(createInvestment()); //pInv1指向createInvestment()返回物;
     std::auto_ptr<Investment> pInv2(pInv1);                      //现在pInv2指向对象,而pInv1被设为NULL;
     pInv1 = pInv2;                                                               //现在pInv1指向对象,而pIn2被设为NULL;

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

     还有一个问题就是,不能让多个auto_ptr同时指向某一个对象。auto_ptr还有一个特性就是,通过复制之后,其raw 对象被置为null。

     所以,我们引用一个  引用计数型智能指针  shared_ptr 。它可以持续跟踪共有多少个对象指向某笔资源,并在无人指向它是自动删除该资源。

    void f()

{

    std::   shared_ptr<investment> plv1(createinvestment());//pInv1指向createInvestment()返回物;

    std::   shared_ptr<investment> plv2(plv1);//pInv1,pInv2指向同一个对象;

    plv1 = plv2;//同上,无变化

}//函数退出,pInv1,pInv2被销毁,它们所指的对象也竟被自动释放。

   还有一个问题就是,上面两个智能指针 auto_ptr 与 shared_ptr在析构函数内只执行 delete 而不是delete[] ,也就意味着,在动态分配的数组上这两个指针也存在风险。这个可能就需要使用boost::   shared_array来帮助了。

记住:

      为防止资源泄露,请使用RAII对象,他们在构造函数中获得资源,在析构函数中释放资源。

      两个比较常用的RAII类分别是auto_ptr和shared_ptr.后者通常都是较佳选择,因为其拷贝比较直观。

2、    在资源管理类中小心拷贝行为

       在堆上申请的资源我们可以用上面的智能指针类去管理,但有些并不适合。这时,我们就需要建立自己的资源管理类。

  void lock(Mutex *pm);     //锁定pm所指的互斥量
  void unlock(Mutex *pm);        //将pm解除锁定
  //   我们建立的资源管理类可能会是这样:
     class Lock 
    {
        public: 
        explicit Lock(Mutex *pm)
        : mutexPtr(pm) 
        {
             lock(mutexPtr); 
        } 
        ~Lock() 
        { 
             unlock(mutexPtr); 
        } 
        private: 
        Mutex *mutexPtr; 
    }; 

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

   当Lock对象被复制,会发生什么?

通常,我们会选择以下两种解决方案:

1、禁止复制

2、对底层资源使用  引用计数法

通常只要内含一个tr1::shared_ptr成员变量,RAII类便可实现”引用计数“行为。

     class Lock

    {

        public:

            explicit Lock(Mutex *pm)

            : mutexPtr(pm, unlock)        //由于tr1::shared_ptr缺省行为是”当引用计数为0时删除其所指物“,幸运的是                                                          //我们可以指定”引用计数“为9时被调用的所谓”删除器“,即第二个参数unlock

        {

            lock(mutexPtr.get());

        }

        private:

std::tr1::shared_ptr<Mutex> mutexPtr;

     };

     本例中,并没说明析构函数,因为没有必要。编译器为我们生成的析构函数会自动调用其non-static成员变量(mutexPtr)的析构函数。而mutexPtr的析构函数会在互斥量”引用计数“为0时自动调用tr1::shared_ptr的删除器(unlock)。

    Copying函有可能被编译器自动创建出来,因此除非编译器所生成版本做了你想要做的事,否则你得自己编写它们。

    记住:

  • 复制RAII对象必须一并复制它所管理的资源,所以资源的copying行为决定RAII对象的copying行为。
  • 普遍而常见的RAII类拷贝行为是:抑制拷贝,施行引用计数法。不过其它行为也可能被实现。 

Effective C++ 条款13/14 以对象管理资源 || 在资源管理类中小心拷贝行为的更多相关文章

  1. Effective C++ -----条款13:以对象管理资源

    为防止资源泄漏,请使用RAII(Resource Acquisiton Is Initialization) 对象,它们在构造函数中获得资源并在析构函数中释放资源. 两个常被使用的RAII class ...

  2. 条款13:以对象管理资源(use objects to manage resources)

    NOTE: 1.为防止资源泄漏,请使用RAII对象,它们在构造函数中获得资源并在析构函数中释放资源. 2.两个常被使用的RAII classes 分别是 trl::shared_ptr 和 auto_ ...

  3. effective C++ 读书笔记 条款14 以对象管理资源

    如果我们使用一个投资行为的程序库: #include "stdafx.h" #include <iostream> #include <memory> us ...

  4. Effective C++(14) 在资源管理类中小心copying行为

    问题聚焦:     上一条款所告诉我们的智能指针,只适合与在堆中的资源,而并非所有资源都是在堆中的.     这时候,我们可能需要建立自己的资源管理类,那么建立自己的资源管理类时,需要注意什么呢?. ...

  5. [Effective C++ --014]在资源管理类中小心copying行为

    第一节 <背景> 条款13中讲到“资源取得的时机便是初始化时机”并由此引出“以对象管理资源”的概念.通常情况下使用std中的auto_ptr(智能指针)和tr1::shared_ptr(引 ...

  6. 【14】在资源管理类中小心copying行为

    1.为什么要使用资源管理类? 资源管理类的思路就是,栈上的对象,封装堆上分配的资源,确保一定会释放资源.auto_ptr和shared_ptr就是资源管理类,行为上像指针. 2.auto_ptr和sh ...

  7. EC笔记:第三部分:13、以对象管理资源

    C++相比Java等含有gc的语言来说,内存管理方面(也包括资源管理)比较令人头疼.一些初级程序员,甚至是一些经验丰富的老程序员,也会经常在资源管理上犯错.这时候就需要一个能够自动管理资源的东西(gc ...

  8. 条款14:在资源管理类中小心copying行为

    请牢记: 1.复制RAII对象必须一并复制它所管理的资源,所以资源的copying行为决定RAII对象的copying行为. 2.普遍常见的RAII class copying行为是:抑制copyin ...

  9. EC笔记:第三部分:14、在资源管理类中小心Copying行为

    场景 上一节实现了智能指针,其中的拷贝构造函数和赋值运算符是通过增加/减少指针的引用计数来操作的.但是如果是管理一个独占资源呢?我们希望在一个资源使用时被锁定,在使用完毕后被释放. #include ...

随机推荐

  1. python中join()函数讲解

    本文简述的是string.join(words[, sep]),它的功能是把字符串或者列表,元组等的元素给连接起来,返回一个字符串,和split()函数与正好相反,看下面的代码理解. a=[" ...

  2. 【10】css hack原理及常用hack

    [10]css hack原理及常用hack 原理:利用不同浏览器对CSS的支持和解析结果不一样编写针对特定浏览器样式.常见的hack有1)属性hack.2)选择器hack.3)IE条件注释 IE条件注 ...

  3. Wp8无广告 锁屏可以持续用的手电筒

    前面的博文写了怎么实现手电筒,界面不够漂亮 我修改了界面之后 提交到了微软的App商店 在这里送上下载地址: http://www.windowsphone.com/zh-cn/store/app/% ...

  4. Appium自动化-基于java的环境搭建

    引言 自动化测试框架搭建主要分为以下几个方面的下载安装及环境配置: 1.jdk 2. adt 3. appium 4. testng插件 工具链接: https://pan.baidu.com/s/1 ...

  5. shell的格式化输出命令printf

    printf 命令用于格式化输出, 是echo命令的增强版.它是C语言printf()库函数的一个有限的变形,并且在语法上有些不同. 注意:printf 由 POSIX 标准所定义,移植性要比 ech ...

  6. 算法复习——求最长不下降序列长度(dp算法)

    题目: 题目背景 161114-练习-DAY1-AHSDFZ T2 题目描述 有 N 辆列车,标记为 1,2,3,…,N.它们按照一定的次序进站,站台共有 K 个轨道,轨道遵从先进先出的原则.列车进入 ...

  7. robotframework安装和配置【转IBM:https://www.ibm.com/developerworks/cn/opensource/os-cn-robot-framework/index.html】

    内容   概览 Robot Framework 介绍 Robot Framework 的安装和配置 RIDE 编辑器介绍 创建测试项目 简单的测试用例的编写 总结 相关主题 评论   Robot Fr ...

  8. Nk 1430 Divisors(因子数与质因数)

    Time Limit: 5000 ms    Memory Limit: 10000 kB   Total Submit : 432 (78 users)   Accepted Submit : 10 ...

  9. Ubuntu Jdk卸载 Oracle Jdk安装

    完全卸载 移除所有 Java相关包 (Sun, Oracle, OpenJDK, IcedTea plugins, GIJ): apt-get update apt-cache search java ...

  10. HDU 4474 Yet Another Multiple Problem【2012成都regional K题】 【BFS+一个判断技巧】

    Yet Another Multiple Problem Time Limit: 40000/20000 MS (Java/Others)    Memory Limit: 65536/65536 K ...