首页 > 代码库 > 第28课 再论智能指针(下)

第28课 再论智能指针(下)

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 = http://www.mamicode.com/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课 再论智能指针(下)