인용 계수 가 있 는 스마트 포인터 구현

스스로 실현 하 는 스마트 포인터:
    장점: 인용 계수 가 있어 포인터 간 에 대상 을 공유 할 수 있 습 니 다.
    단점: 배열 의 동적 분 배 를 실현 할 수 없다.
    auto_cptr.h:
#ifndef _AUTO_CPTR_H_
#define _AUTO_CPTR_H_

//#define __debug
// auto_cptr.h
//           
#include <iostream>
using namespace std;



template <typename T>
class auto_cptr
{
public:
    auto_cptr():p(0),count(0)
    {
        #ifdef __debug
        cout<<"auto_cptr():empty construction of auto_cptr"<<endl;
        #endif
    }
    
    template <typename U>
    explicit auto_cptr(U *pu):p( (T*)pu ),count(0)
    {

        if(pu)
        {
            count=new size_t;
            *count = 1;
            #ifdef __debug
            cout<<"auto_cptr(U *pu): construction of auto_cptr, obj="<<p<<", count="<<get_count()<<"  "<<endl;
            #endif
        }else
        {
            #ifdef __debug
            cout<<"auto_cptr(U *pu): construction of auto_cptr, null=null"<<endl;
            #endif
        }
    }
    
    auto_cptr(const auto_cptr<T>& cp):p( 0 ),count(0)
    {

        copyfrom(cp);
        #ifdef __debug
        cout<<"auto_cptr(const auto_cptr<T>& cp):copy construction of auto_cptr.obj="
        <<p<<", count="<<get_count()<<"  "<<endl;
        #endif
    }
    

    auto_cptr<T>& operator=(const auto_cptr <T>&cp)
    {
        if(&cp==this)
            return *this;
        copyfrom(cp);
        #ifdef __debug
        cout<<"auto_cptr::operator=:operator"<<"obj="<<p<<", count="<<get_count()<<"  "<<endl;
        #endif
        
        return *this;
    }

    ~auto_cptr()
    {
        #ifdef __debug
        cout<<"~auto_cptr()"<<endl;
        #endif
        minus();
    }
    
    friend bool operator==(const auto_cptr<T>&p1,const auto_cptr<T>&p2)
    {
        return p1.p==p2.p && p1.count==p2.count;
    }
    friend bool operator!=(const auto_cptr<T>&p1,const auto_cptr<T>&p2)
    {
        return !(p1==p2);
    }
    
    T *operator->() {return &(operator*());}
    T &operator*() {return *p;}
    
    size_t get_count()
    {
        return count?*count:0;
    }
    
    T* get_pvalue()
    {
        return p;
    }
    
private:
    void copyfrom(const auto_cptr<T> &cp)
    {
        minus();
        if(cp.p)
        { 
            p=cp.p;
            count=cp.count;
            ++(*count);

        }    
    } 
    
    void minus()
    {
        if(p==0)
            return;
        --(*count);
        if(*count<=0)
        {
            #ifdef __debug
            cout<<"auto_cptr::minus(): delete "<<endl;
            #endif
            delete p;
            delete count;
        }else
        {
            #ifdef __debug
            cout<<"auto_cptr::minus():not delete, p="<<p<<", count="<<get_count()<<"  "<<endl;
            #endif
        }
        
        p=0;
        count=0;
    }
    
private:
    T  *p;
    size_t *count;
};

#endif

테스트: main. c:

#include <iostream>

#define __debug   //            
#include "auto_cptr.h"
using namespace std;

//    

class A

{

public:

    A(){cout<<"empty construction"<<endl;}

    A(int a_){cout<<"non-empty construction"<<endl;_a=a_;}

    ~A(){cout<<"deconstruction"<<endl;}
    void display(){cout<<"A::display()"<<endl;}

    friend ostream &operator<<(ostream &os, const A&a);    

    private:

    int _a;

};


ostream &operator<<(ostream &os, const A&a)

{

    cout<<a._a;

    return os;

}




int main()

{

    

    auto_cptr<A> p1=auto_cptr<A> (new A(5) );

    auto_cptr<A> p2=p1; //     
    auto_cptr<A>p3;     //       
    p3=p2;              //        
    
    p2=auto_cptr<A>();  //       p2

    cout<<"        : "<<*p3<<endl;              // operator *
    cout<<"          : ";   p3->display();    // operator ->
    
    

    return 0;

}


실행:
chen@chen-book1:~$ gcc c.cpp -lstdc++ -o cpp -g
chen@chen-book1:~$ ./cpp
non-empty construction
auto_cptr(U *pu): construction of auto_cptr, obj=0x9c3c008, count=1  
auto_cptr(const auto_cptr<T>& cp):copy construction of auto_cptr.obj=0x9c3c008, count=2  
auto_cptr():empty construction of auto_cptr
auto_cptr::operator=:operatorobj=0x9c3c008, count=3  
auto_cptr():empty construction of auto_cptr
auto_cptr::minus():not delete, p=0x9c3c008, count=2  
auto_cptr::operator=:operatorobj=0, count=0  
~auto_cptr()
        : 5
          : A::display()
~auto_cptr()
auto_cptr::minus():not delete, p=0x9c3c008, count=1  
~auto_cptr()
~auto_cptr()
auto_cptr::minus(): delete 
deconstruction
chen@chen-book1:~$ 

좋은 웹페이지 즐겨찾기