zoukankan      html  css  js  c++  java
  • Effective C++ 笔记 —— Item 13: Use objects to manage resources.

    Consider this code:

    class Investment { /*...*/ }; // root class of hierarchy of investment types
    
    Investment* createInvestment(); // return ptr to dynamically allocated object in the Investment hierarchy;
                                    // the caller must delete it (parameters omitted for simplicity)
    
    void f()
    {
        Investment *pInv = createInvestment(); // call factory function use pInv
        // ...
        delete pInv; // release object
    }

    This looks okay, but there are several ways f could fail to delete the investment object it gets from createInvestment.

    Here's how to use auto_ptr to prevent f's potential resource leak:

    void f()
    {
        std::auto_ptr<Investment> pInv(createInvestment()); // call factory function use pInv as before automatically delete pInv via auto_ptr’s dtor
        // ...
    }

    Because an auto_ptr automatically deletes what it points to when the auto_ptr is destroyed, it’s important that there never be more than one auto_ptr pointing to an object. If there were, the object would be deleted more than once, and that would put your program on the fast track to undefined behavior. To prevent such problems, auto_ptrs have an unusual characteristic: copying them (via copy constructor or copy assignment operator) sets them to null, and the copying pointer assumes sole ownership of the resource!

    std::auto_ptr<Investment> // pInv1 points to the object returned from createInvestment
    pInv1(createInvestment()); 
    
    std::auto_ptr<Investment> pInv2(pInv1); // pInv2 now points to the object; pInv1 is now null object, and pInv2 is null
    
    pInv1 = pInv2; // now pInv1 points to the

    An alternative to auto_ptr is a reference-counting smart pointer (RCSP). An RCSP is a smart pointer that keeps track of how many objects point to a particular resource and automatically deletes the resource when nobody is pointing to it any longer. As such, RCSPs offer behavior that is similar to that of garbage collection. Unlike garbage collection, however, RCSPs can’t break cycles of references (e.g., two otherwise unused objects that point to one another).

    void f()
    {
        //...
        std::tr1::shared_ptr<Investment>
        pInv(createInvestment()); // call factory function use pInv as before automatically delete pInv via shared_ptr’s dtor
        //... 
    }
    void f()
    {
        // ...
        std::tr1::shared_ptr<Investment> // pInv1 points to the object returned from createInvestment
        pInv1(createInvestment());  
    
        std::tr1::shared_ptr<Investment> pInv2(pInv1); // both pInv1 and pInv2 now point to the object
            
        pInv1 = pInv2; // ditto — nothing has changed ...
    } // pInv1 and pInv2 are destroyed, and the object they point to is automatically deleted

    Both auto_ptr and tr1::shared_ptr use delete in their destructors, not delete [].That means that using auto_ptr or tr1::shared_ptr with dynamically allocated arrays is a bad idea.

    You may be surprised to discover that there is nothing like auto_ptr or tr1::shared_ptr for dynamically allocated arrays in C++, not even in TR1. That’s because vector and string can almost always replace dynamically allocated arrays. If you still think it would be nice to have auto_ptr- and tr1::shared_ptr-like classes for arrays, look to Boost.

    Things to Remember:

    • To prevent resource leaks, use RAII objects that acquire resources in their constructors and release them in their destructors.
    • Two commonly useful RAII classes are tr1::shared_ptr and auto_ptr. tr1::shared_ptr is usually the better choice, because its behavior when copied is intuitive. Copying an auto_ptr sets it to null.
  • 相关阅读:
    C#开发微信门户及应用(18)-微信企业号的通讯录管理开发之成员管理
    C#开发微信门户及应用(17)-微信企业号的通讯录管理开发之部门管理
    C#开发微信门户及应用(16)-微信企业号的配置和使用
    C#开发微信门户及应用(15)-微信菜单增加扫一扫、发图片、发地理位置功能
    会员管理系统的设计和开发(3)--主界面的设计思路分享
    会员管理系统的设计和开发(2)-- RDLC报表的设计及动态加载
    Winform开发中常见界面的DevExpress处理操作
    在WCF数据访问中使用缓存提高Winform字段中文显示速度
    双指针算法模板和一些题目
    尾递归 递归函数中,递归调用是整个函数体中最后的语句,且它的返回值不属于表达式的一部分时,这个递归调用就是尾递归,空间复杂度是O(1)
  • 原文地址:https://www.cnblogs.com/zoneofmine/p/15213886.html
Copyright © 2011-2022 走看看