1. 程式人生 > >第28課 再論智能指針(下)

第28課 再論智能指針(下)

生命 cout 模板 main.c 堆內存 1.5 endif color 可能

1. SharedPointer的設計

(1)使用類模板,通過計數機制標識堆內存

(2)堆內存被指向時,refCount++

(3)指針被置空時:refCount—

(4)當refCount == 0時,釋放堆內存

2. 計數機制原理剖析

技術分享

3. SharedPointer類的聲明

template <typename T>
class SharedPointer : public Pointer<T>
{
protected:
    int m_refCount; //計數機制成員
public:
    SharedPointer(T* p = NULL);
    SharedPointer(
const SharedPointer<T>& obj); SharedPointer<T>& operator=(const SharedPointer<T>& obj); void clear(); //將當前指針置為空 //由於SharedPointer支持多個對象同時指向一片堆空間 //因此必須支持比較操作! bool operator==(const SharedPointer<T>& obj); bool operator!=(const
SharedPointer<T>& obj); ~SharedPointer(); };

4. 智能指針使用軍規

(1)只能用來指向堆空間中的單個對象(變量)

(2)不同類型的智能指針對象不能混合使用

(3)不要使用delete釋放智能指針指向的堆空間

【編程實驗】SharedPointer智能指針的實現

//Pointer.h

#ifndef _POINTER_H_
#define _POINTER_H_

#include "Object.h"

namespace DTLib {

template <typename T>
class
Pointer : public Object //Object是析構函數本身是純虛函數! { protected: T* m_pointer; public: Pointer(T* p = NULL) { m_pointer = p; } T* operator->() { return m_pointer; } T& operator*() { return *m_pointer; } const T* operator->() const { return m_pointer; } const T& operator*() const { return *m_pointer; } bool isNull() const { return (m_pointer == NULL); } T* get() const { return m_pointer; } }; } #endif // _POINTER_H_

//SharedPointer.h

#ifndef _SHAREDPOINTER_H_
#define _SHAREDPOINTER_H_

#include "Pointer.h"

namespace DTLib
{

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

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

        ++this->m_refCount;
    }

public:
    SharedPointer(T* p = NULL) : m_refCount(0)
    {
        if(p){
            this->m_pointer = p;
            m_refCount++;
        }
    }

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

    SharedPointer<T>& operator=(const SharedPointer<T>& obj)
    {
        if(this != &obj){
            clear(); //this可能指向另一堆對象內存,要先置空

            assign(obj);

        }
        return *this;
    }


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

        this->m_pointer = NULL;

        --this->m_refCount;

        if(m_refCount == 0)
            delete toDel;
    }

    //由於SharedPointer支持多個對象同時指向一片堆空間。因此必須支持比較操作!
    bool operator==(const SharedPointer<T>& obj)
    {
        return (this->m_pointer == obj.m_pointer);
    }

    bool operator!=(const SharedPointer<T>& obj)
    {
        return (this->m_pointer != obj.m_pointer);
    }

    ~SharedPointer()
    {
        clear();
    }
};

}

#endif // _SHAREDPOINTER_H_

//main.cpp

#include <iostream>
#include "SharedPointer.h"

using namespace std;
using namespace DTLib;

class Test : public Object
{
public:
    int value;

    Test(): value(0)
    {
        cout << "Test()" << endl;
    }

    ~Test()
    {
        cout <<"~Test()" << endl;
    }
};

int main()
{
    //const SharedPointer<Test> sp0 = new Test();
    SharedPointer<Test> sp0 = new Test();
    SharedPointer<Test> sp1 = sp0;
    SharedPointer<Test> sp2 = NULL;

    sp2 = sp1;

    sp0->value = 100;

    cout << sp0->value << endl;
    cout << sp1->value << endl;
    cout << sp2->value << endl;

    //sp1.clear();

    cout << (sp0==sp1) << endl;

    return 0;
}
/*輸出結果
Test()
100
100
100
1
~Test()
*/

5. 小結

(1)SharedPointer最大程度的模擬了原生指針的行為

(2)計數機制確保多個智能指針合法的指向同一片堆空間

(3)智能指針只能用於指向堆空間中的內存

(4)不同類型的智能指針不要混合使用

(5)堆對象的生命周期由智能指針進行管理

第28課 再論智能指針(下)