美文网首页
28_再论智能指针(下)

28_再论智能指针(下)

作者: 编程半岛 | 来源:发表于2018-07-09 14:59 被阅读10次

    关键词:SharedPointer类的实现

    0. SharedPointer类图

    SharedPointer类图

    2. SharedPointer设计要点——计数机制

    • 通过计数机制(ref)标识堆内存
      当堆内存被指向时:++ref
      当指针被置空时:--ref
      ref==0时:释放堆空间
      计数机制原理图

    3. SharedPointer类的声明

    template < typename T >
    class SharedPointer : public Pointer<T>
    {
    protected:
        int* m_ref;     // 计数机制成员指针
    public:
        SharedPointer(T* p = NULL);
        SharedPointer(const SharedPointer<T>& obj);
        SharedPointer<T>& operator= (const SharedPointer<T>& obj);
        void clear();   // 将当前指针置为空
        ~SharedPointer();
    };
    

    由于SharedPointer支持多个对象同时指向一片堆空间,因此,必须支持比较操作

    4. SharedPointer类的实现

    SharedPointer

    #ifndef SHAREDPOINTER_H
    #define SHAREDPOINTER_H
    
    #include "cstdlib"
    #include "Exception.h"
    #include "Pointer.h"
    
    namespace DTLib
    {
    
    template < typename T >
    class SharedPointer : public Pointer<T>
    {
    protected:
        int* m_ref;     // 计数机制成员指针
        void assign(const SharedPointer<T>& obj);
    public:
        SharedPointer(T* p = NULL);
        SharedPointer(const SharedPointer<T>& obj);
        SharedPointer<T>& operator= (const SharedPointer<T>& obj);
        void clear();   // 将当前指针置为空
        ~SharedPointer();
    };
    
    template < typename T >
    SharedPointer<T>::SharedPointer(T* p) : m_ref(NULL)
    {
        if( p )
        {
            this->m_ref = static_cast<int*>(std::malloc(sizeof(int)));   // 给m_ref分配堆内存空间
    
            if( this->m_ref )
            {
                *(this->m_ref) = 1;     // 申请成功后,计数赋值为1
                this->m_pointer = p;
            }
            else
            {
                THROW_EXCEPTION(NoEnoughMemoryExcetion, "No memory to create SharedPointer object...");
            }
        }
    }
    
    template < typename T >
    void SharedPointer<T>::assign(const SharedPointer<T>& obj)
    {
        this->m_ref = obj.m_ref;
        this->m_pointer = obj.m_pointer;
    
        if( this->m_ref )
        {
            ++(*this->m_ref);
        }
    }
    
    template < typename T >
    SharedPointer<T>::SharedPointer(const SharedPointer<T>& obj)
    {
        assign(obj);
    }
    
    template < typename T >
    SharedPointer<T>& SharedPointer<T>::operator= (const SharedPointer<T>& obj)
    {
        if( this != &obj)   // 避免自赋值
        {
            clear();
    
            assign(obj);
        }
    
        return *this;
    }
    
    template < typename T >
    void SharedPointer<T>::clear()
    {
        T* toDel = this->m_pointer;
        int* ref = this->m_ref;
    
        this->m_pointer = NULL;
        this->m_ref = NULL;
    
        if( ret )       // 判断计数变量是否合法
        {
            --(*ref);       // 将计数变量减1
    
            if( *ref == 0 ) // 判断计数变量是否为0
            {
                free(ref);  //  释放计数变量的堆空间
    
                delete toDel;   // 销毁堆空间
    
            }
        }
    }
    
    template < typename T >
    SharedPointer<T>::~SharedPointer()
    {
        clear();
    }
    
    /* 通过全局函数重载 == 操作符*/
    template < typename T >
    bool operator== (const SharedPointer<T>& l, const SharedPointer<T>& r)
    {
        return l.get() == r.get();
    }
    
    /* 通过全局函数重载 != 操作符*/
    template < typename T >
    bool operator!= (const SharedPointer<T>& l, const SharedPointer<T>& r)
    {
        return !(l == r);
    }
    
    }
    
    #endif // SHAREDPOINTER_H
    

    5. 智能指针的使用军规

    • 只能用来指向堆空间中的单个变量/对象
    • 不同类型的智能指针对象不能混合使用
    • 不要使用delete释放智能指针指向的堆空间

    6. 小结

    • SharedPointer最大程度的模拟了原生指针的行为
    • 计数机制确保了多个智能指针合法的指向同一片堆空间
    • 智能指针只能用于指向堆空间中的内存
    • 不同类型的智能指针不要混合使用
    • 堆对象的生命周期由智能指针进行管理

    声明:此文章仅是本人在学习狄泰学院《数据结构实战开发教程》所做的笔记,文章中包含狄泰软件资料内容,一切版权归狄泰软件所有!
    实验环境:ubuntu10 + Qt Creator2.4.1 + Qt SDK 4.7.4

    相关文章

      网友评论

          本文标题:28_再论智能指针(下)

          本文链接:https://www.haomeiwen.com/subject/irnouftx.html