• 《Effective C++》学习笔记条款13 以对象管理资源


     

    条款 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 pointerSCSP)、它可以持续跟踪共有

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

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

    auto_ptrtr1::shared_ptr是个潜在危险,资源得不到释放。也许boost::scoped_arrayboost::shared_array能提供

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

        请记住:

    • 为防止资源泄漏,请使用RAII对象,它们在构造函数中获得资源并在析构函数中释放资源。
    • 两个常被使用的RAII类分别是auto_ptr和tr1::shared_ptr。后者通常是较佳选择,因为其拷贝行为比较直观。若选择auto_ptr,复制动作会使他(被复制物)指向NULL。   
  • 相关阅读:
    .Net常见笔试题
    冒泡排序算法 C#版
    Bundle捆绑压缩技术
    异步Ajax
    HtmlHelper总结
    HtmlHelper的扩展分页方法
    WCF
    程序猿值得看的几个技术网站(记录)
    Struts2和SpringMVC的区别
    nginx配置文件作用介绍
  • 原文地址:https://www.cnblogs.com/fuhaots2009/p/3476536.html
Copyright © 2020-2023  润新知