使用过COM 的人,应该对智能指针不陌生,CComPtr 和 CComQIPtr 可以替我们分担了管理对象生命周期的任务, 不需要我们操心对象到底什么时候应该释放. 废话不多说了,让我们也来实现这样的一个智能指针吧. 该智能指针可以管理对象的生命周期.
当然要实现CComPtr 在COM 对象创建方面的功能就要做进一步扩展了.
需要用到的知识:
1.要让该智能适用于每一个类,那么C++ Template 肯定要应用上的. 也即是我们这个智能指针其实是一个模板类
2.由于该指针指向的我们需要管理的对象只有一个,因此我们用记数器记录下有多少个智能指针引用到了该对象, 第二个智能指针的生成我们通过第一个来初始化,因此,需要我们实现Copy Constructor, 和=赋值运算符的重载.
3.由于我们需要在使用智能指针象使用该智能指针指向对象一样,因此我们需要overload -> 运算符.
首先看看:SMpointer.h 的template 声明吧>
template <typename T> class CSMpointer
{
public:
CSMpointer(T *); // 我们只实现一个构造函数,要求传入一个我们需要处理的类别
~CSMpointer(void);
CSMpointer(const CSMpointer<T> & org); //拷贝构造函数
CSMpointer<T> & operator=(const CSMpointer<T> &); //重载=赋值运算符. 非必要
const CSMpointer<T> & operator*(void)const; //重载*赋值运算符. 非必要
CSMpointer<T> & operator*(void);//重载*赋值运算符.必要
const T * & operator->(void)const;.////重载->赋值运算符. 可以使我们使用该智能指针象使用该智能指针指向的类一样必要
T * & operator->(void);//重载->赋值运算符.
int getCount(); //获取引用计数
private:
T * m_pObj; //只能指针指向的类对象
int * m_useCount;//引用计数
};
再类看看实现吧:SMpointer.cpp
#include "SMpointer.h"
template <typename T>
CSMpointer<T>::CSMpointer(T * p):m_pObj(p),m_useCount(NULL)
{
m_useCount=new int(1);
}
template <typename T>
CSMpointer<T>::~CSMpointer(void)
{
if(--*m_useCount==0) //引用计数为0时,我们才真正删除我们指向的对象.
delete m_pObj;
}
template <typename T>
CSMpointer<T>::CSMpointer(const CSMpointer<T> & org):m_pObj(org.m_pObj)
{
printf("use copy constructor \n");
m_useCount=org.m_useCount;
(*m_useCount)+=1;
}
template <typename T>
CSMpointer<T> & CSMpointer<T>::operator=(const CSMpointer<T> &)
{
printf("use assigment operator \n");
if(m_useCount&&(--*m_useCount)==0)
delete m_pObj;
m_useCount=org.m_useCount;
(*m_useCount)+=1;
m_pObj=org.m_pObj;
return *this;
}
template <typename T>
const CSMpointer<T> & CSMpointer<T>::operator*(void)const
{
return *this;
}
template <typename T>
CSMpointer<T> & CSMpointer<T>::operator*(void)
{
return *this;
}
template <typename T>
const T * & CSMpointer<T>::operator->(void)const
{
return this->m_pObj;
}
template <typename T>
T * & CSMpointer<T>::operator->(void)
{
return this->m_pObj;
}
template <typename T>
int CSMpointer<T>::getCount()
{
return *(this->m_useCount);
}
//再类看看使用: 我们假设有一个CStudent 的类
#include "SMpointer.cpp" //注意需要引用.SMpointer.cpp 而不是.h 文件,原因是我们需要在compiler的时候看到真个template implement .否则会出现Link Error.
#include "Student.h"
main:
int _tmain(int argc, _TCHAR* argv[])
{
CStudent * c;
c=new CStudent();
c->m_age=10;
c->m_name="Trevor Yang";
{
CSMpointer <CStudent> CStuPtr_org(c);
printf("in of the block Large \n");
printf("CStuPtr_org Object Count %d \n",CStuPtr_org.getCount());
{ //block 1
printf("in the block1 \n");
CSMpointer <CStudent> CStuPtr(CStuPtr_org);
printf("CStuPtr Object Count %d \n",CStuPtr.getCount());
CSMpointer <CStudent> CStuPtr2=CStuPtr;
printf("CStuPtr2 Object Count %d \n",CStuPtr2.getCount());
printf("out of the block1 \n");
}
printf("CStuPtr_org Object Count %d \n",CStuPtr_org.getCount());
printf("student age is %d",CStuPtr_org->getAge()); //就象使用CStudent 对象一样,归功于->的重载
printf("out of the block Large \n");
}
getchar();
return 0;
}
//可以看到该智能指针已经帮助我们管理了对象的生命周期,我们不需要担心出现Dangling Pointer 的问题.