带引用计数的智能指针(模板类)实现的3种方法


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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值