1. 程式人生 > >資料結構 筆記:SharedPointer類實現

資料結構 筆記:SharedPointer類實現

使用智慧指標(SmartPointer)替換單鏈表(LinkList)中的原生指標是否可行?

問題

-SmartPointer的設計方案

·指標宣告週期結束時主動釋放堆空間

·一片堆空間最多隻能由一個指標標識

·杜絕指標運算和指標比較

新的設計方案

-Pointer是智慧指標的抽象父類(模板)

·純虛解構函式virtual ~Pointer() = 0;

·過載operator -> ()

·過載operator * ()

template <typename T>
class Pointer : public Object
{
protected:
    T* m_pointer;

public:
    Pointer(T* p = NULL)
    {
        m_pointer = p;
    }

    T* operator-> ()
    {
        return m_pointer;
    }

    T& operator* ()
    {
        return *m_pointer;
    }

    bool isNULL()
    {
        return (m_pointer == NULL);
    }

    T* get()
    {
        return m_pointer;
    }
};

SharedPointer類的具體實現

-類模板

·通過技術機制(ref)標識堆記憶體

~堆記憶體被指向時:ref++

~指標被置空時:ref--

~ref == 0 時:釋放堆記憶體

template <typename T>
class SharedPointer : public Pointer<T>
{
protected:
    int* m_ref;    //計數機制成員指標

    void assign(const SharedPointer<T>& obj)
    {
        this->m_ref = obj.m_ref;
        this->m_pointer = obj.m_pointer;

        if(this->m_ref)
        {
            (*this->m_ref)++;
        }
    }

public:
    SharedPointer(T* p = NULL) : m_ref(NULL)
    {
        if(p)
        {
            this->m_ref =  static_cast<int*>(malloc(sizeof(int)));

            if(this->m_ref )
            {
                *(this->m_ref) = 1;
                this->m_pointer = p;
            }
            else
            {
                //丟擲異常
            }
        }
    }

    SharedPointer(const SharedPointer<T>& obj) : Pointer<T>(NULL)
    {
        assign(obj);
    }

    SharedPointer<T>& operator = (const SharedPointer<T>& obj)
    {
        if(this != &obj)
        {
            clear();

            assign(obj);
        }

        return *this;
    }

    void clear()//將當前指標置為空
    {
        T* toDel = this->m_pointer;
        int* ref = this->m_ref;

        this->m_pointer = NULL;
        this->m_ref = NULL;

        if(ref)
        {
            (*ref)--;
            if(*ref == 0)
            {
                free(ref);

                delete toDel;
            }
        }
    }

    ~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);
}

智慧指標的比較

由於SharedPointer支援多個物件同時指向一片堆空間;因此,必須支援比較操作!

智慧指標的使用軍規

-只能用來指向堆空間中的單個變數(物件)

-不同型別的智慧指標物件不能混合使用

-不要使用delete釋放智慧指標指向的堆空間

總結:

-SharedPointer最大程度的模擬了原生指標的行為

-計數機制確保多個智慧指標合法的指向同一片堆空間

-智慧指標智慧用於指向堆空間中的記憶體

-不同型別的智慧指標不要混合使用

-堆物件的宣告週期由智慧指標進行管理