最近在阅读Gamebryo的文档,先读的Object System这部分。Gamebryo中从NiRefObject继承下来的类都支持引用计数,也就是说支持0引用下对象自动销毁。
一直以来都听闻智能指针的大名,平常项目中并没有使用过,所以也一直没抽空去研究,今天花了点时间自己实现了一个智能指针。
要实现一个智能指针就要先实现一个支持引用计数的类,主要负责增加计数,减少计数,销毁持有的对象指针。大致实现如下:
class RefObject
template
class RefObject
{
public:
explicit RefObject(T* p):m_RefCount(1),m_pContainer(p)
{
}
~RefObject()
{
decRef();
}
void incRef()
{
++m_RefCount;
}
void decRef()
{
if(--m_RefCount == 0)
{
destroy();
}
}
T* getPtr()
{
return m_pContainer;
}
private:
void destroy()
{
delete m_pContainer;
m_pContainer = 0;
m_RefCount = 0;
delete this;
}
private:
T* m_pContainer;
unsigned int m_RefCount;
private:
RefObject(const RefObject&);
const RefObject& operator= (const RefObject&);
};
该模板类将持有一个使用者指定的对象T类型的指针,并维护该指针被引用的数量。在destroy函数中销毁T类型指针和自己。为什么要删除自己呢?这是因为RefObject将和T共存亡。因为我希望用户可以将任意类放入智能指针内部,而不是从RefObject继承下来。所以 RefObject是为T而生(由SmartPtr new出来的)。当用户直接使用RefObject时需要自己去调用incRef和decRef去增加和减少计数,因此即将设计的类SmartPtr实际上就是封装下RefObject,不需要用户来调这两个函数。SmartPtr实现大致如下:
class SmartPtr
template
class SmartPtr
{
public:
SmartPtr():m_pRefObject(0)
{
}
explicit SmartPtr(T* p)
{
m_pRefObject = new RefObject
(p);
}
SmartPtr(const SmartPtr& other):m_pRefObject(other.m_pRefObject)
{
m_pRefObject->incRef();
}
~SmartPtr()
{
if(m_pRefObject)
m_pRefObject->decRef();
}
const SmartPtr
& operator= (const SmartPtr& other)
{
if(m_pRefObject != other.m_pRefObject)
{
m_pRefObject = other.m_pRefObject;
m_pRefObject->incRef();
}
return *this;
}
T* operator-> () const
{
return m_pRefObject->getPtr();
}
T& operator* () const
{
return *m_pRefObject->getPtr();
}
protected:
RefObject
* m_pRefObject;
};