Smart pointers about C ++

  When the time has a pointer member of a class , there are two ways to manage the pointer member: First, by way of the control value type, each class object retains a copy of the object pointer; Another more elegant way is smart pointers, in order to achieve a shared pointer to the object .

  Smart pointers (smart pointer) to implement a common technique is to use a reference count (COUNT Reference) . Smart pointer class counter with a point associated with the object class, the class has a pointer to track the reference count how many objects point to the same object .

  The difference between the ordinary and the smart pointer that the pointer smart pointer is actually a pointer to add a layer of ordinary encapsulation mechanism, one object of this encapsulation mechanism is provided to enable smart pointers can easily manage the lifetime of an object .

  In C ++, we know that, if you use an ordinary pointer to create a pointer to an object pointer, then after you are finished using the object we need to remove it yourself, for example:

ObjectType* temp_ptr = new ObjectType();

temp_ptr->foo();

delete temp_ptr;

  Many materials will point out that if the programmer forgets to delete temp_ptr after calling temp_ptr finished, it will result in a dangling pointer (dangling pointer), that is to say the pointer now points to memory area whose content programmers can not grasp and control, it may It is likely to cause a memory leak.

  But in fact, not just "forget" in the above paragraph of this program, if foo () throws an exception at run time, then temp_ptr pointed objects are still not safe to delete.

  At this time, the emergence of smart pointers is actually easy to control the lifetime of objects in smart pointers in an object when and under what conditions to be destructed or deleted by the smart pointer itself is decided, users do not need to manage.

  There are four types of smart pointers : Quote from https://www.zhihu.com/question/20368881/answer/14918675

1) scoped_ptr: This is a relatively simple smart pointer, as the name of the, scoped_ptr pointed object is automatically obtained outside the scope of destruction, one example is: https://www.boost.org/ doc / libs / 1_50_0 / libs /
smart_ptr / scoped_ptr.htm in addition, non-copyable scoped_ptr is, that you can not to try to copy the contents of a scoped_ptr scoped_ptr another, this is to prevent erroneous multiple destructor the same object pointer points.

2) shared_ptr:  A lot of people understand is actually smart pointers shared_ptr this category. shared_ptr is implemented in essence reference count (reference counting), that is to say shared_ptr support replication of, replication of a reference frequency and a shared_ptr is added to this smart pointer 1, and when the number of times the smart pointer referenced reduced to 0 when the object is automatically destructed. Of particular note is that if a ring appears the relationship, then the number of citations ring on the subject are certainly can not be reduced to the characterization of reference shared_ptr 0 then it will not be removed, in order to solve this problem introduced weak_ptr.

3) weak_ptr:  for weak_ptr role played by a lot of people have their own different interpretations, the biggest difference and shared_ptr weak_ptr I understand that in weak_ptr point to an object when its reference count does not increase, so that you can use to point to a weak_ptr object and when weak_ptr still point to the object's destructor it, when you re-visit this time of weak_ptr, weak_ptr in fact return would be an empty shared_ptr. In fact, when the normal internal shared_ptr implementation is not a reference to the maintenance of the count, but two reference count represents a strong reference, which is counted when copying with shared_ptr carried out, it is a weak reference, which is used weak_ptr counting the time of copying. weak_ptr itself does not increase the strong reference value, and the strong reference reduced to zero, the object is automatically destructed. Why take weak_ptr to solve the problem just described cyclic references to it? Note that the contradictory nature of cyclic references are not in any way to break the programming language, in order to solve cyclic references, the first step must first break the loop, that is to tell C ++, which is quoted on the ring weakest, it can be broken, so in a loop as long as the original one shared_ptr into weak_ptr, essentially the loop can be broken, the original circular reference problem can not be brought destructor along with it has been resolved.

4) intrusive_ptr:  Simply put, the difference between intrusive_ptr and shared_ptr is that it points to an object intrusive_ptr required to achieve a reference counting mechanism itself, that is to say when the object itself contains a reference counter, you can use intrusive_ptr. In actual use, I almost never seen intrusive_ptr ...

The problem with traditional pointer:
  When you create an object on the heap, the system took the life of the object entirely to you, when used up, the system will not recover resources, but you need to release it.
Well, if it wants to be responsible for the release of the object in question, it is necessary to know when and where to release the release. If you do not deal with these two issues, it will cause a memory leak problems or program crashes .

// resource leaks referred str1 memory has not been released 1 
{
     String * str1 = new new  String ( " Hello " );
     String * str2 = new new  String ( " World " ); 
} 

// 2 multiple-release, causing crashes 
{
     String str1 = * new new  String ( " Hello " );
     Delete str1;
     // ... 
    Delete str1; // crash the program 
}

  In the above example, the release pointer is carried out in the same scope, they can easily avoid the problem in the above code in programming.
  However, for a large project, the object created in one place, and may not be released in the corresponding scope, but wait until the case of certain events, exception handling, etc. will go to destroy the object, for such problems often it is difficult to come out of the investigation.
  Therefore, it is necessary to cite a mechanism for responsible self-destruct pointer. Rather than by the programmer to manually destroy itself. Smart pointers is precisely such a mechanism.

Reference counting smart pointers principles: (From: almost known: dry laying adzuki Jun)

1. When applying for a resource from the heap, we create a smart pointer object to point to this resource, while the heap apply a resource for counting, so that later all objects are pointing to the resource sharing the count of resources, so that the number of reference count on only one.
2. When the object assigned to the object ptr1 ptr2, which shared reference count becomes 2.
3. ptr2 delete the object, its reference count is reduced to the corresponding 1.
4. Delete ptr1 object reference count goes to zero, the release of resources.

From the following code: almost known: dry laying Roo Jun

#pragma Once 

Template < class T>
 class SharedPointer 
{ 
public :
     // default constructor, an internal pointer does not point to any resource reference count is 0, because it is not bound to any resource 
    SharedPointer (): m_refCount (nullptr) , m_pointer (nullptr a) {} 
    
    // constructor, when initialized to point to an already-allocated resources 
    SharedPointer (T * adoptTarget): m_refCount (nullptr a), m_pointer (adoptTarget) 
    { 
        AddReference (); 
    } 
    
    // constructor other objects create a new object 
    SharedPointer ( const SharedPointer <T> & Copy) 
        : m_refCount (copy.m_refCount), m_pointer (copy.m_pointer) 
    {  
        AddReference ();
    } 
    
    //Destructor, reference counting down, when time is 0, the resource is released 
    Virtual ~ SharedPointer () 
    { 
        RemoveReference (); 
    } 
    
    // assignment
     // When the left is assigned a value indicating that it no longer points to the resource referred to, so Save a reference count
     // after that it points to a new resource, reference resource corresponding to this count by one 
    SharedPointer <T> & operator = ( const SharedPointer <T> & that) 
    { 
        IF ( the this ! = & that) 
        { 
            RemoveReference (); 
            the this -> m_pointer = that.m_pointer;
             the this -> m_refCount = return that.m_refCount;
            AddReference (); 
        }
         * the this ; 
    } 
    
    // determines whether or not point to the same resource 
    BOOL  operator == ( const SharedPointer <T> & OTHER) 
    { 
        return m_pointer == other.m_pointer; 
    } 
    BOOL  operator = (! const SharedPointer <T> & OTHER) 
    { 
        return ! operator == (OTHER); 
    } 
    
    // dereferencing 
    T & operator * () const 
    { 
        return * m_pointer; 
    } 
    // call the object's public member known 
    T * operator-> () const 
    { 
        return m_pointer; 
    } 
    
    // Get a reference count number 
    int GetReferenceCount () const 
    { 
        IF (m_refCount) 
        { 
            return * m_refCount; 
        } 
        the else 
        { 
            return - . 1 ; 
        } 
    } 
    
protected :
     // When in nullpter, create a reference count of resources, and is initialized to 1
     // otherwise, the reference count is incremented. 
    void AddReference () 
    { 
        IF  (m_refCount)
        { 
            ( * m_refCount) ++ ; 
        } 
        the else 
        { 
            m_refCount = new new  int ( 0 );
             * = m_refCount . 1 ; 
        } 
    } 
    
    // reference count by one, becomes 0 when releasing all resources 
    void RemoveReference () 
    { 
        IF (m_refCount) 
        { 
            ( * m_refCount) - ;
             IF (* m_refCount == 0 ) 
            { 
                Delete m_refCount;
                 Delete m_pointer; 
                m_refCount = 0 ;
                m_pointer = 0;
            }
        }
    }
    
private:
    int * m_refCount;
    T   * m_pointer;
};

 

reference:

https://baike.baidu.com/item/%E6%99%BA%E8%83%BD%E6%8C%87%E9%92%88/10784135?fr=aladdin

https://zhuanlan.zhihu.com/p/63488452

https://www.zhihu.com/question/20368881/answer/14918675

Guess you like

Origin www.cnblogs.com/Flash-ylf/p/11615731.html