Example to use shared_ptr?

后端 未结 7 1321
孤城傲影
孤城傲影 2020-12-02 05:08

Hi I asked a question today about How to insert different types of objects in the same vector array and my code in that question was

 gate* G[1000];
G[0] =         


        
7条回答
  •  长情又很酷
    2020-12-02 05:37

    Learning to use smart pointers is in my opinion one of the most important steps to become a competent C++ programmer. As you know whenever you new an object at some point you want to delete it.

    One issue that arise is that with exceptions it can be very hard to make sure a object is always released just once in all possible execution paths.

    This is the reason for RAII: http://en.wikipedia.org/wiki/RAII

    Making a helper class with purpose of making sure that an object always deleted once in all execution paths.

    Example of a class like this is: std::auto_ptr

    But sometimes you like to share objects with other. It should only be deleted when none uses it anymore.

    In order to help with that reference counting strategies have been developed but you still need to remember addref and release ref manually. In essence this is the same problem as new/delete.

    That's why boost has developed boost::shared_ptr, it's reference counting smart pointer so you can share objects and not leak memory unintentionally.

    With the addition of C++ tr1 this is now added to the c++ standard as well but its named std::tr1::shared_ptr<>.

    I recommend using the standard shared pointer if possible. ptr_list, ptr_dequeue and so are IIRC specialized containers for pointer types. I ignore them for now.

    So we can start from your example:

    std::vector G; 
    G.push_back(new ANDgate);  
    G.push_back(new ORgate); 
    for(unsigned i=0;iRun(); 
    } 
    

    The problem here is now that whenever G goes out scope we leak the 2 objects added to G. Let's rewrite it to use std::tr1::shared_ptr

    // Remember to include  for shared_ptr
    // First do an alias for std::tr1::shared_ptr so we don't have to 
    // type that in every place. Call it gate_ptr. This is what typedef does.
    typedef std::tr1::shared_ptr gate_ptr;    
    // gate_ptr is now our "smart" pointer. So let's make a vector out of it.
    std::vector G; 
    // these smart_ptrs can't be implicitly created from gate* we have to be explicit about it
    // gate_ptr (new ANDgate), it's a good thing:
    G.push_back(gate_ptr (new ANDgate));  
    G.push_back(gate_ptr (new ORgate)); 
    for(unsigned i=0;iRun(); 
    } 
    

    When G goes out of scope the memory is automatically reclaimed.

    As an exercise which I plagued newcomers in my team with is asking them to write their own smart pointer class. Then after you are done discard the class immedietly and never use it again. Hopefully you acquired crucial knowledge on how a smart pointer works under the hood. There's no magic really.

提交回复
热议问题