条款 13 :以对象管理资源

例:
     voidf()
     { 
         Investment *pInv = createInvestment(); 
         ...                  //这里存在诸多“不定因素”,可能造成delete pInv;得不到执行,这可能就存在潜在的内存泄露。
         delete pInv;
     }

 解决方法:把资源放进对象内,我们便可依赖C++的“析构函数自动调用机制”确保资源被释放。
    许多资源被动态分配于堆内而后被用于单一区块或函数内。它们应该在控制流离开那个区块或函数时被释放。标准

程序库提供的auto_ptr正是针对这种形势而设计的特制产品。auto_ptr是个“类指针对象”,也就是所谓的“智能指针”,

其析构函数自动对其所指对象调用delete。

void f()
     { 
        std::auto_ptr<Investment> pInv(createInvestment()); 
         ... 
     }         //函数退出,auto_ptr调用析构函数自动调用delete,删除pInv;无需显示调用delete。

“以对象管理资源”的两个关键想法:

  • 获得资源后立刻放进管理对象内(如auto_ptr)。每一笔资源都在获得的同时立刻被放进管理对象中。“资源取得时机便是初始化时机”(Resource Acquisition Is Initialization;RAII)。
  • 管理对象运用析构函数确保资源被释放。即一旦对象被销毁,其析构函数被自动调用来释放资源。

由于auto_ptr被销毁时会自动删除它所指之物,所以不能让多个auto_ptr同时指向同一对象。所以auto_ptr若通

过copying函数复制它们,它们会变成NULL,而复制所得的指针将取得资源的唯一拥有权!

看下面例子:

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

pInv1 = pInv2;                                                           //现在pInv1指向对象,而pIn2被设为NULL;

受auto_ptr管理的资源必须绝对没有一个以上的auto_ptr同时指向它。即“有你没我,有我没你”。
      auto_ptr的替代方案是“引用计数型智能指针”(reference-counting smart pointer;SCSP)、它可以持续跟踪共有

多少对象指向某笔资源,并在无人指向它时自动删除该资源。

TR1的tr1::shared_ptr就是一个"引用计数型智能指针"。
     void f()
     { 
         ... 
        std::tr1::shared_ptr<Investment>  pInv1(createInvestment()); //pInv1指向createInvestment()返回物;
        std::tr1::shared_ptr<Investment> pInv2(pInv1);                    //pInv1,pInv2指向同一个对象;
         pInv1 = pInv2;                                                                     //同上,无变化
         ... 
     }        //函数退出,pInv1,pInv2被销毁,它们所指的对象也竟被自动释放。
       auto_ptr和tr1::shared_ptr都在其析构函数内做delete而不是delete[],也就意味着在动态分配而得的数组身上使

用auto_ptr或tr1::shared_ptr是个潜在危险,资源得不到释放。也许boost::scoped_array和boost::shared_array能提供

帮助。还有,vector和string几乎总是可以取代动态分配而得的数组。

请记住:

  • 为防止资源泄漏,请使用RAII对象,它们在构造函数中获得资源并在析构函数中释放资源。
  • 两个常被使用的RAII类分别是auto_ptr和tr1::shared_ptr。后者通常是较佳选择,因为其拷贝行为比较直观。若选择auto_ptr,复制动作会使他(被复制物)指向NULL。

最新文章

  1. javascript之小积累-匿名函数表达式的最佳实践
  2. 判断scrollview是否滚动到了底部
  3. VisualSVN Server的配置和使用方法 图文
  4. 排队打饭 sdut 2443【最简单的贪心法应用举例】
  5. textViewDidChange: crashes in iOS 7
  6. python os.path 模块
  7. .net MVC全局定时器执行作业
  8. Windows下MySQL数据库备份脚本(二)
  9. block 做参数
  10. bzoj1003[ZJOI2006]物流运输trans
  11. matlab 中max函数用法
  12. 51Nod 1284 2 3 5 7的倍数 容斥原理
  13. cookie/session(过时的写法)
  14. 欢迎进入我的个人博客 anzhan.me
  15. java学习——递归
  16. 【学习总结】Git学习-参考廖雪峰老师教程八-使用GitHub
  17. 建立Oracle GoldenGate凭证
  18. 玩转X-CTR100 l STM32F4 l MPU6050加速度陀螺仪传感器
  19. Monitor Minio server with Prometheus
  20. NopCommerce 执行计划任务不同Services协调操作导致更新数据失败的问题!

热门文章

  1. 读《CSCW的一种建模与实现方法》
  2. wpf RadioButton控件的一个bug,onpropertychanged后会修改旧属性的值
  3. 解决Android SDK Manager更新(一个更新Host的程序的原理实现和源码)
  4. uva 1396 - Most Distant Point from the Sea
  5. MDN &gt; Web technology for developers &gt; HTTP
  6. HTML5 Geolocation
  7. Linq 筛选出一条数据
  8. POJ_1220_Nmber Sequence
  9. 搭建Eclipse C/C++开发环境
  10. 产品设计中先熟练使用铅笔 不要依赖Axure