智能指针设计原理以及实现

学习《游戏编程全接触》时看到智能指针,于是便用自己的方式写了一次。 

智能指针原理:通过重载运算符,在指向一个新内存地址时为其创建计数器,而在一个智能指针指向一个另一个智能指针时,如果指向的那个智能指针的地址跟自己指向的不同,则令计数器++,在指针销毁时,则令计数器--,当智能指针销毁时,销毁变量和计数器达到对对象的动态回收。

// TestPtr.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <assert.h>

#define SHOW_SMART_PTR_DEBUG_INFOR 100
class A
{
public:
 virtual void showInfor()
 {
  printf("i am a/n");
 }
};
class B : public A
{
public:
 void showInfor()
 {
  printf("i am a/n");
 }
 
};
class C
{
public :
 
 int count;
 C()
 {
  count = 50;
 }
 
};

template<class T>class SmartPtr  ;
template<class T> class RefCounter
{
 friend class SmartPtr<T>;
 
 int count;
 T*  m_instance;
 
 //构造一个对某对象引用进行计数的RefCounter,
 RefCounter(T* instance)
 {
  m_instance = instance;
  count = 1;//存在一个引用
 }
 
 //引用++
 void addRef()
 {
  count++;
#ifdef SHOW_SMART_PTR_DEBUG_INFOR
  printf("addRef, count = %d/n",count);
#endif
  
 }
 //引用--
 void minusRef()
 {
  count--;
#ifdef SHOW_SMART_PTR_DEBUG_INFOR
  printf("minusRef, count = %d/n",count);
#endif
  
  assert(count>=0);
  //如果引用数为0,释放内存
  if(count == 0)
  {
#ifdef SHOW_SMART_PTR_DEBUG_INFOR
   printf("release");
#endif
   release();
  }
 }
 //删除内存
 void release()
 {
  if(NULL != m_instance)
   delete m_instance;
 }
 //返回引用
 T* getRef()
 {
  return m_instance;
 }
 
 
};
template<class T>class SmartPtr 
{
 friend class SmartPtr<T>;
private:
 RefCounter<T> *m_refCounter;
public:
 
 SmartPtr()
 {
  m_refCounter = NULL;
 }
 
 virtual ~SmartPtr()
 {
  
  if(NULL != m_refCounter)
  {
#ifdef SHOW_SMART_PTR_DEBUG_INFOR
   printf(" ~SmartPtr/n");
#endif
   m_refCounter->minusRef();
   if(NULL == m_refCounter)
   {
    delete m_refCounter;
    m_refCounter = NULL;
   }
  }
 }
 
 
 SmartPtr(T* instance)
 {
 
  
  
  if(NULL == instance)//传入一个空值
  {
   m_refCounter = NULL;
  }
  else//传入非空地址时,创建RefCounter对象
  {
   m_refCounter = new RefCounter<T>(instance);
  }
 
 }

 SmartPtr(const SmartPtr &sp)
 {
  m_refCounter = sp.m_refCounter;
  //指向的不为空时,引用数++
  if(NULL != m_refCounter)
    m_refCounter->addRef();
  
 }
 //指向一个对象
 SmartPtr& operator = (T* instance)
 {
  
  //如果指针原来指向的地址跟现在所指向的地址一致的话,不做任何操作
  if(NULL != m_refCounter && m_refCounter->getRef() == instance)
  {
   return *this;
  }
  RefCounter<T> *oldCounter = m_refCounter;
  
  
  if(NULL == instance)//传入一个空值
  {
   m_refCounter = NULL;
  }
  else//传入非空地址时,创建RefCounter对象
  {
   m_refCounter = new RefCounter<T>(instance);
  }
  //旧地址的引用计数--
  if(NULL != oldCounter)
  {
   oldCounter->minusRef();
   if(0 == oldCounter)
   {
    delete oldCounter;
    oldCounter = NULL;
   }
  }
  
  
  return *this;
 }
 
 //指向一个智能指针时
 SmartPtr& operator = (const SmartPtr &sp)
 {
  RefCounter<T> *oldCounter = m_refCounter;
  m_refCounter = sp.m_refCounter;
  if(oldCounter != m_refCounter)
  {
   //指向的不为空时,引用数++
   if(NULL != m_refCounter)
    m_refCounter->addRef();
   //旧地址的引用计数--
   if(NULL != oldCounter)
   {
    oldCounter->minusRef();
    if(0 == oldCounter)
    {
     delete oldCounter;
     oldCounter = NULL;
    }
   }
  }
  
  return *this;
 }
 
 //重载强制转型运算符
 operator T*()const
 {
  return getPtr();
 }
 //重载指针运算符
 T* operator ->()
 {
  assert(NULL != getPtr());
  return getPtr();
 }
 
 
 T* getPtr() const
 {
  return (NULL == m_refCounter ? NULL ; m_refCounter->getRef());
 }
 
 
};


int main(int argc, char* argv[])
{
 printf("Hello World!/n");
 
 //SmartPtr<A> a = new A();
 /*SmartPtr<B> b = new B();
 a->showInfor();
 b->showInfor();*/
 
 
 
 SmartPtr<C> e;
 SmartPtr<C> f = new C();
 SmartPtr<C> g;
 SmartPtr<C> h = f;
 
 printf("/n");
 printf("e = new C();/n");
 e = new C();
 printf("f = e;/n");
 f = e;
 printf("g = e;/n");
 g = e;
 printf("h = f;/n");
 h = f;
 
 
 printf("/n");
 printf("e = new C();/n");
 e = new C();
 printf("f = e;/n");
 f = e;
 printf("g = e;/n");
 g = e;
 printf("h = f;/n");
 h = f;
 
 
 /*printf("/n");
 printf("e = new C();/n");
 e = new C();
 printf("f = e;/n");
 f = e;
 printf("g = e;/n");
 g = e;
 printf("h = f;/n");
 h = f;*/


 
 
 
 return 0;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值