Implementation of smart Pointers-implementation and principle of reference counting

Source: Internet
Author: User

Implementation of smart Pointers-implementation and principle of reference counting
I. When smart pointers are programmed in C ++, when there are pointer members in the class, there are generally two ways to manage pointer members: one is to manage them in a value-type way, each class Object retains a copy of the object to which the Pointer Points. Another more elegant way is to use a smart pointer to share the object to which the Pointer Points. A common implementation technology of smart pointer is the use of reference count ). The smart pointer class associates a counter with the object to which the class points. The reference counting class tracks how many objects in the class share the same pointer. Each time a new object of the class is created, the pointer is initialized and the reference count is set to 1. when an object is created as a copy of another object, copy the constructor to copy the pointer and add the corresponding reference count. when an object is assigned a value, the value assignment operator reduces the reference count of the object indicated by the left operand (if the reference count is reduced to 0, delete the object), and increase the reference count of the object indicated by the right operand. when calling the destructor, The Destructor reduces the reference count (if the reference count is reduced to 0, the basic object is deleted ).II. General implementation of smart pointers

Smart pointers are usually implemented using class templates. Simulate various behaviors of class pointers. However, its most important role is to manage class pointer members to prevent the appearance of suspension pointers.

template
 
    class SmartPointer{      public:          SmartPointer(T *t):pt(t){}          T& operator *(){ return *pt; }          T* operator ->() { return pt; }      private:          T *pt;  };  
 
Iii. Implementation of reference count

To implement reference counting, we define a _ counter class to record the number of references and set all the members of the _ counter class to private, because other types do not need to access _ counter, only SmartPointer can operate on it, And SmartPointer will be set as its friend Meta class.

class _counter{      template
 
   friend class SmartPointer;      _counter(int u):use(u){}      ~_counter(){}      int use;  };  
 

In the SmartPointer class, the _ counter pointer is retained.

Template
 
  
Class SmartPointer {public: SmartPointer (T * t): pc (new _ counter (1) {cout <"SmartPointer: SmartPointer () invoded use is:" <
  
   
Use <
   
    
Pt = t;} SmartPointer (SmartPointer
    
     
& Rhs) {this-> pc = rhs. pc; this-> pt = rhs.pt; this-> pc-> use ++; cout <"SmartPointer copy invoked use is:" <
     
      
Use <
      
        Use --; cout <"SmartPointer ::~ SmartPointer () invoded use is: "<
       
         Use <
        
          Use = 0) {delete pt; delete pc;} SmartPointer
         
           & Operator = (SmartPointer
          
            Rhs) {if (rhs = * this) {return * this ;}
           
           
            
           if
           (--pc->use==0){
            
           delete 
           pt;
            
           delete 
           pc;
            
           }This-> pt = rhs.pt; this-> pc = rhs. pc; this-> pc-> use ++; cout <"SmartPointer: operator = () invoked use is:" <
           
             Use <
            
             

For example, we have a HasPtr class, and one of its class members is the pointer * p.


Class HasPtr {public: HasPtr (int val): value (val), p (new int (3) {cout <"HasPtr: HasPtr () invoked" <
              
               

If the call is as follows:

HasPtr *php = new HasPtr(3);  SmartPointer
                
                  psp(php);  SmartPointer
                 
                   npsp(psp);
                 
                

We now have two smart pointer objects pointing to the same HasPtr object. The model is as follows:

_ Counter's use Member (reference count) is 2.

Iv. Test
int main(void)  {      HasPtr *php = new HasPtr(3);      SmartPointer
                
                  psp(php);      SmartPointer
                 
                   npsp(psp);      SmartPointer
                  
                    nnpsp = npsp;          return 0;  }  
                  
                 
                

Using the gcc compiler, the running result is as follows:

Find another implementation:

<喎?http: www.bkjia.com kf ware vc " target="_blank" class="keylink"> VcD4KPHByZSBjbGFzcz0 = "brush: java;"> # include # Include Using namespace std; # define SAFE_DELETE (p) if (p) {delete p; p = NULL;} class KRefCount {public: KRefCount (): m_nCount (0) {} public: unsigned AddRef () {return InterlockedIncrement (& m_nCount);} unsigned Release () {return InterlockedDecrement (& m_nCount);} void Reset () {m_nCount = 0;} private: unsigned long m_nCount;}; template Class SmartPtr {public: SmartPtr (void): m_pData (NULL) {m_pReference = new KRefCount (); m_pReference-> AddRef ();} SmartPtr (T * pValue ): m_pData (pValue) {m_pReference = new KRefCount (); m_pReference-> AddRef ();} SmartPtr (const SmartPtr & Sp): m_pData (sp. m_pData), m_pReference (sp. m_pReference) {m_pReference-> AddRef ();}~ SmartPtr (void) {if (m_pReference & m_pReference-> Release () = 0) {SAFE_DELETE (m_pData); SAFE_DELETE (m_pReference);} inline T & operator *() {return * m_pData;} inline T * operator-> () {return m_pData;} SmartPtr & Amp; operator = (const SmartPtr & Sp) {if (this! = & Sp) {if (m_pReference & m_pReference-> Release () = 0) {SAFE_DELETE (m_pData); SAFE_DELETE (m_pReference);} m_pData = sp. m_pData; m_pReference = sp. m_pReference; m_pReference-> AddRef ();} return * this;} SmartPtr & Operator = (T * pValue) {if (m_pReference & m_pReference-> Release () = 0) {SAFE_DELETE (m_pData); SAFE_DELETE (m_pReference);} m_pData = pValue; m_pReference = new KRefCount; m_pReference-> AddRef (); return * this;} T * Get () {T * ptr = NULL; ptr = m_pData; return ptr ;} void Attach (T * pObject) {if (m_pReference-> Release () = 0) {SAFE_DELETE (m_pData); SAFE_DELETE (m_pReference);} m_pData = pObject; m_pReference = new KRefCount; m_pReference-> AddRef ();} T * Detach () {T * ptr = NULL; if (m_pData) {ptr = m_pData; m_pData = NULL; m_pReference-> Reset ();} return ptr;} private: KRefCount * m_pReference; T * m_pData ;}; class CTest {public: CTest (int B): a (B) {} private: int a ;}; int main () {SmartPtr PSmartPtr1 (new CTest (10); SmartPtr PSmartPtr2 (new CTest (20); pSmartPtr1 = pSmartPtr2 ;}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.