C++ 智能指针实现

    1、问题的提出

    先看下面的例子:

    class CText

    {

        public:

            CText(int *&ptr):m_ptr(ptr)

            {

            }

            ~CText()

            {

                delete m_ptr;

            }

        private:

            int *m_ptr;

    };

    int FunText()

    {

        int *ptr = new int;

        CText CText1(ptr);

        CText CText2(ptr);

        return 0;

    }

    在函数FunText()中,类的两个对象共用了new出来的指针ptr。当函数运行开始时,调用两次构造函数;退出运行时,调用两次析构函数,而在第一次调用时已经delete ptr,因而第二次调用时将会出现错误。

    以上例子说明,当类中有指针成员时,必须明确何时才是操作delete指针的时机。智能指针能够解决上述问题。

 

    2、智能指针的原理

    前面的例子运行时出现的错误系第二次析构时“无ptr可delete”所致。为解决这个问题,我们可以这样设想:定义一个计数变量int counter = 0,每次调用构造函数时,counter加1,调用析构函数时,counter减1。当counter等于0时,delete ptr。这样在函数退出时就不会有错误了。这种实现技术称之为引用计数。

    智能指针需要运用引用计数技术。当然,这里就不再是定义计数变量那么简单了。依据C++的封装性,我们定义一个计数器类CCounter,负责对计数变量的操作。

    class CCounter

    {

    public:

        CCounter();

        ~CCounter();

    public:

        void AddCounter();

        void DecCounter();

    private:

        UINT m_unCounter;

    };

    应用智能指针,其实就是建立一个智能指针类CSmartPointer。CSmartPointer将CCouter与CSmartPointer对象相关联,CCouter负责记录有多少个CSmartPointer对象共用同一指针。

    template <class T>

    class CSmartPointer

    {

    public:

        CSmartPointer(T *);

        CSmartPointer(const CSmartPointer<T> & );

        CSmartPointer<T> &operator=(const CSmartPointer<T> &);

        ~CSmartPointer();

    private:

        T *m_pointer;

    };

    类CSmartPointer负责如下功能

    ◆ 创建对象时,初始化类指针成员并调用AddCounter();

    ◆ 对象作为另一对象的副本而创建时,拷贝指针并调用AddCounter();

    ◆ 对对象进行赋值时,赋值运算符左边对象调用关联的DecCounter(),拷贝指针后,赋值运算符右边对象调用关联的AddCounter()。

    ◆ 调用析构函数,析构函数调用DecCounter()。

 

    3、代码实现

    类CCounter定义与实现:

    //CCounter.h

    #ifndef _CCOUNTER_H_

    #define _CCOUNTER_H_

    class CCounter  //要使用智能指针的类须继承该类

    {

    public:

        CCounter();

        ~CCounter();

    public:

        void AddCounter();

        void DecCounter();

    private:

        UINT m_unCounter;

    };

    #endif

 

    //CCounter.cpp

    #include"CCounter.h"

    CCounter::CCounter():m_unCounter(0)

    {

    }

 

    CCounter::~CCounter()

    {

        assert(0 == m_unCounter);

    }

 

    void CCounter::AddCounter()

    {

        m_unCounter++;

    }

 

    void CCounter::DecCounter()

    {

        m_unCounter--;

        assert(m_unCounter >= 0);

        if (m_unCounter == 0)

        {

           delete this;

        } 

    }

    模板类CSmartPointer的定义与实现:

    //CSmartPointer.h
    #include"CCounter.h"
    template <class T>
    class CSmartPointer
    {
    public:
        CSmartPointer(T *);
        CSmartPointer(const CSmartPointer<T> &);
        CSmartPointer<T> &operator=(const CSmartPointer<T> &);
        ~CSmartPointer();
    private:
        T *m_pointer;
    };

    template <class T>
    CSmartPointer<T>::CSmartPointer(T *pointer = NULL):m_pointer(pointer)
    {
        if (NULL != m_pointer)
        {
            m_pointer->AddCounter();
        }
    }

    template <class T>
    CSmartPointer<T>::CSmartPointer(const CSmartPointer<T> &refSP)
    {
        if (NULL != refSP.m_pointer)
        {
            m_pointer = refSP.m_pointer;
            m_pointer->AddCounter();
        }
    }


    template <class T>
    CSmartPointer<T> &CSmartPointer<T>::operator =(const CSmartPointer<T> &refSP)
    {
        if (this != &refSP)  //不是本身
        {
            if (NULL != m_pointer)
            {
                m_pointer->DecCounter();
            }
 
            m_pointer = refSP.m_pointer;
            if (NULL != m_pointer)
            {
                m_pointer->AddCounter();
            }
        }
    }


    template <class T>
    CSmartPointer<T>::~CSmartPointer()
    {
        if (NULL != m_pointer)
        {
            m_pointer->DecCounter();
        } 
    }

    则可在主函数main()中,编写如下代码:

    // main.cpp
    #include" CSmartPointer.h"

    class CText:public CCounter

    {

        public:

            CText(int *&ptr):m_ptr(ptr)

            {

            }

            ~CText()

            {

                delete m_ptr;

            }

        private:

            int *m_ptr;

    };


    int main()

    {
        CText *pCText = new CText;

        CSmartPointer<CText> p1CSmartPointer(pCText);

        CSmartPointer<CText> p2CSmartPointer(pCText);

        CSmartPointer<CText> p3CSmartPointer(p2CSmartPointer);

        return 0;

    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值