带引用计数的智能指针(模板类)

带引用计数的智能指针(模板类)
1. 非侵入式:static map<unsigned int, int>,key是对象地址,value是counter。
2. 非侵入式:构造函数new一个int作为counter,拷贝构造函数和赋值操作符中传递该counter。
3. 侵入式:定义一个Count基类自带counter,所有对象继承与Count基类,counter在对象中。
方法2无法重载 operator = (T *t),因为无法从参数中获得t的counter信息。

Code1: 用static map作为counter
#include  < stdio.h >
#include 
< map >

using   namespace  std;


class  A
{
public :
    A()
    {
        printf(
" \nA Construct\n " );
    }
    
    
~ A()
    {
        printf(
" \nA Destruct\n " );
    }
};

class  B
{
public :
    B()
    {
        printf(
" \nB Construct\n " );
    }
    
    
~ B()
    {
        printf(
" \nB Destruct\n " );
    }
};

template 
< typename T >
class  SmartPtr
{
public :
    SmartPtr(T 
* t)
    {
        Pointee 
=  t;
        
        map
< unsigned  int int > ::iterator it  =  CountMap.find((unsigned  int )t);
        
if (it  !=  CountMap.end())
            
++ (it -> second);
        
else
            CountMap[(unsigned 
int )Pointee]  =   1 ;
    }
    
    SmartPtr(
const  SmartPtr  & sp)
    {
        Pointee 
=  sp.Pointee;
        
        map
< unsigned  int int > ::iterator it  =  CountMap.find((unsigned  int )Pointee);
        
if (it  !=  CountMap.end())
            
++ (it -> second);
        
else
            CountMap[(unsigned 
int )Pointee]  =   1 ;
    }
    
    SmartPtr
&   operator   =  ( const  SmartPtr  & sp)
    {
        
if (NULL  !=  Pointee)
        {
            
-- CountMap[(unsigned  int )Pointee];
            
if (CountMap[(unsigned  int )Pointee]  ==   0 )
            {
                CountMap.erase((unsigned 
int )Pointee);
                delete Pointee;
                Pointee 
=  NULL;
            }
        }
        
        Pointee 
=  sp.Pointee;
        
        map
< unsigned  int int > ::iterator it  =  CountMap.find((unsigned  int )Pointee);
        
if (it  !=  CountMap.end())
            
++ (it -> second);
        
else
            CountMap[(unsigned 
int )Pointee]  =   1 ;
        
        
return   * this ;
    }
    
    SmartPtr
&   operator   =  (T  * t)
    {
        
if (NULL  !=  Pointee)
        {
            
-- CountMap[(unsigned  int )Pointee];
            
if (CountMap[(unsigned  int )Pointee]  ==   0 )
            {
                CountMap.erase((unsigned 
int )Pointee);
                delete Pointee;
                Pointee 
=  NULL;
            }
        }
        
        Pointee 
=  t;
        
        map
< unsigned  int int > ::iterator it  =  CountMap.find((unsigned  int )Pointee);
        
if (it  !=  CountMap.end())
            
++ (it -> second);
        
else
            CountMap[(unsigned 
int )Pointee]  =   1 ;
        
        
return   * this ;
    }
    
    
~ SmartPtr()
    {
        
if (NULL  !=  Pointee)
        {
            
-- CountMap[(unsigned  int )Pointee];
            
if (CountMap[(unsigned  int )Pointee]  ==   0 )
            {
                CountMap.erase((unsigned 
int )Pointee);
                delete Pointee;
                Pointee 
=  NULL;
            }
        }
    }
private :
    T 
* Pointee;
    
static  map < unsigned  int int >  CountMap;
    SmartPtr();
};

template 
< typename T >  
map
< unsigned  int int >  SmartPtr < T > ::CountMap;

int  main()
{
    A 
* objA1  =   new  A();
    A 
* objA2  =   new  A();
    A 
* objA3  =   new  A();
    B 
* objB1  =   new  B();
    B 
* objB2  =   new  B();
    B 
* objB3  =   new  B();
    
    SmartPtr
< A >  sPtrA1(objA1);
    SmartPtr
< A >  sPtrA2(objA2);
    sPtrA1 
=  sPtrA2;
    sPtrA1 
=  objA3;
    sPtrA2 
=  objA3;
    
    SmartPtr
< B >  sPtrB1(objB1);
    SmartPtr
< B >  sPtrB2(objB2);
    sPtrB1 
=  sPtrB2;
    sPtrB1 
=  objB3;
    sPtrB2 
=  objB3;
    
return   0 ;
}

Code2: 用new int作为counter
#include  < stdio.h >

class  A
{
public :
    A()
    {
        printf(
" \nA Construct\n " );
    }
    
    
~ A()
    {
        printf(
" \nA Destruct\n " );
    }
};

class  B
{
public :
    B()
    {
        printf(
" \nB Construct\n " );
    }
    
    
~ B()
    {
        printf(
" \nB Destruct\n " );
    }
};

template 
< typename T >
class  SmartPtr
{
public :
    SmartPtr(T 
* t)
    {
        Pointee 
=  t;

        Count 
=   new   int ( 0 );
        
++ ( * Count);
    }
    
    SmartPtr(
const  SmartPtr  & sp)
    {
        Pointee 
=  sp.Pointee;
        Count 
=  sp.Count;
        
++ ( * Count);
    }
    
    SmartPtr
&   operator   =  ( const  SmartPtr  & sp)
    {
        
if (NULL  !=  Pointee)
            
-- ( * Count);
        
if ( * Count  ==   0 )
            delete Pointee;
        
        Pointee 
=  sp.Pointee;
        Count 
=  sp.Count;
        
++ ( * Count);
        
        
return   * this ;
    }
    
    
//  Cannot work well.
    
//  Should not public this method.
    SmartPtr &   operator   =  (T  * t)
    {
        
if (NULL  !=  Pointee)
            
-- ( * Count);
        
if ( * Count  ==   0 )
        {
            delete Pointee;
            delete Count;
        }
        Pointee 
=  t;
        
//  Cannot get the counter on t.
        Count  =   new   int ( 0 );
        
++ ( * Count);
        
        
return   * this ;
    }
    
    
~ SmartPtr()
    {
        
if (NULL  !=  Pointee)
            
-- ( * Count);
        
if ( * Count  ==   0 )
        {
            delete Pointee;
            Pointee 
=  NULL;
        }
        delete Count;
    }
private :
    T 
* Pointee;
    
int   * Count;
    SmartPtr();
};

int  main()
{
    A 
* obj1  =   new  A();
    A 
* obj2  =   new  A();
    A 
* obj3  =   new  A();
    B 
* objB1  =   new  B();
    B 
* objB2  =   new  B();
    B 
* objB3  =   new  B();
    
    SmartPtr
< A >  sPtr1(obj1);
    SmartPtr
< A >  sPtr2(obj2);
    sPtr1 
=  sPtr2;
    sPtr1 
=  obj3;
    
//  Comment out since SmartPtr cannot get the existing counter on obj3.
    
// sPtr2 = obj3;
    
    SmartPtr
< B >  sPtrB1(objB1);
    SmartPtr
< B >  sPtrB2(objB2);
    sPtrB1 
=  sPtrB2;
    sPtrB1 
=  objB3;
    
//  Comment out since SmartPtr cannot get the existing counter on objB3.
    
// sPtrB2 = objB3;
     return   0 ;
}

Code3: 对象继承与Count基类,counter在对象内
#include  < stdio.h >

class  ReferenceCount
{
public :
    
virtual   ~ ReferenceCount(){};
    
int  Count;
protected :
    ReferenceCount():Count(
0 ){};
};

class  Intrusive:  public  ReferenceCount
{
public :
    Intrusive()
    {
        printf(
" \nInstrusive Construct\n " );
    }
    
    
~ Intrusive()
    {
        printf(
" \nInstrusive Destruct\n " );
    }
};


class  B:  public  ReferenceCount
{
public :
    B()
    {
        printf(
" \nB Construct\n " );
    }
    
    
~ B()
    {
        printf(
" \nB Destruct\n " );
    }
};

template 
< typename T >
class  SmartPtrIntrusive
{
public :
    SmartPtrIntrusive(T 
* t)
    {
        Pointee 
=  t;
        
++ Pointee -> Count;
    }
    
    SmartPtrIntrusive(
const  SmartPtrIntrusive  & sp)
    {
        Pointee 
=  sp.Pointee;
        
++ Pointee -> Count;
    }
    
    SmartPtrIntrusive
&   operator   =  ( const  SmartPtrIntrusive  & sp)
    {
        
if (NULL  !=  Pointee)
            
-- Pointee -> Count;
        
if (Pointee -> Count  ==   0 )
        {
            delete Pointee;
            Pointee 
=  NULL;
        }
        
        Pointee 
=  sp.Pointee;
        
++ Pointee -> Count;
        
        
return   * this ;
    }
    
    SmartPtrIntrusive
&   operator   =  (T  * t)
    {
        
if (NULL  !=  Pointee)
            
-- Pointee -> Count;
        
if (Pointee -> Count  ==   0 )
        {
            delete Pointee;
            Pointee 
=  NULL;
        }

        Pointee 
=  t;
        
++ Pointee -> Count;
        
        
return   * this ;
    }
    
    
~ SmartPtrIntrusive()
    {
        
if (NULL  !=  Pointee)
            
-- Pointee -> Count;
        
if (Pointee -> Count  ==   0 )
        {
            delete Pointee;
            Pointee 
=  NULL;
        }
    }
private :
    T 
* Pointee;
    SmartPtrIntrusive();
};

int  main()
{
    Intrusive 
* obj1  =   new  Intrusive();
    Intrusive 
* obj2  =   new  Intrusive();
    Intrusive 
* obj3  =   new  Intrusive();
    B 
* objB1  =   new  B();
    B 
* objB2  =   new  B();
    B 
* objB3  =   new  B();
    SmartPtrIntrusive
< Intrusive >  sPtr1(obj1);
    SmartPtrIntrusive
< Intrusive >  sPtr2(obj2);
    sPtr1 
=  sPtr2;
    sPtr1 
=  obj3;
    sPtr2 
=  obj3;
    
    SmartPtrIntrusive
< B >  sPtrB1(objB1);
    SmartPtrIntrusive
< B >  sPtrB2(objB2);
    sPtrB1 
=  sPtrB2;
    sPtrB1 
=  objB3;
    sPtrB2 
=  objB3;
    
return   0 ;
}

你可能感兴趣的:(带引用计数的智能指针(模板类))