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