C++ 智能指针的实现

        使用过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 的问题.



你可能感兴趣的:(C++,object,delete,Class,compiler,Constructor)