数据结构 第28课 再论智能指针(下)---------1---------狄泰软件学院

引用文章: 1

引用文章: 2

SharedPointer.h

#ifndef SHAREDPOINTER_H
#define SHAREDPOINTER_H

#include <cstdlib>
#include "Pointer.h"
#include "Exception.h"


// --> 计数变量和堆中的对象,生命周期相同, 都是在堆空间中,两者相关联


namespace DTLib
{
    
    
template <typename T>
class SharedPointer : public Pointer<T>
{
    
    
protected:
    int* m_ref;  // 指针要指向堆空间中创建出来的计数变量

    void assign(const SharedPointer<T>& obj) // 用于拷贝构造函数
    {
    
    
        this->m_ref = obj.m_ref;         // 将当前SharedPointer对象的m_ref成员指针指向了对应着的计数变量
        this->m_pointer = obj.m_pointer; // 将当前SharedPointer对象的m_ref成员指针指向了对应着的堆内存

        if(this->m_ref) // 使用了计数机制,计数变量要加1
        {
    
    
            (*this->m_ref)++;
        }
    }

public:
    SharedPointer(T* p = NULL) : m_ref(NULL)
    {
    
    
        if(p != NULL)
        {
    
    
            this->m_ref = reinterpret_cast<int*>(std::malloc(sizeof(int)));  // 在堆空间中创建一个计数变量
                                                        // malloc 返回值是void* ,因此要做强制类型转换
            if(this->m_ref )
            {
    
    
                *(this->m_ref) = 1;  // 意味着,参数指针p 所指向的堆空间,已经有了一个SharedPointer智能指针对象来指向了
                this->m_pointer = p; // 用this->m_pointer成员指针,指向参数指针p所对应着的堆空间
            }
            else
            {
    
    
                THROW_EXCEPTION(NoEnoughMemoryException, "no enough to create m_ref Object");
            }
        }
    }

    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)--;           // 对象不指向堆空间了,堆空间关联的计数变量-1,
            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());  // 此处有报错,原因:get()不是const函数,get() 和isNull()  加const就行
}                                 // 两个指针操作符 需要重载


template <typename T>
bool operator!=(const SharedPointer<T>& l, const SharedPointer<T>& r)
{
    
    
    return (!(l == r)); // 不相等重载  使用   相等重载 来实现
}


}

#endif // SHAREDPOINTER_H



/*

多个对象指向同一片堆空间,还能够自动释放

智能指针的比较
由于SharedPointer支持多个对象同时指向一片堆空间,因此必须支持比较操作
只有这样才能最大程度的模拟原生指针的行为。



*/






Pointer.h

#ifndef POINTER_H
#define POINTER_H

#include "Object.h"

namespace DTLib
{
    
    
template < typename T >
class Pointer : public Object
{
    
    
protected:
    T* m_pointer;
public:
    Pointer(T* pointer = NULL)
    {
    
    
        m_pointer = pointer;
    }

    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




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()
{
    
    

    /*测验一
    SharedPointer<Test> sp0 = new Test();
    SharedPointer<Test> sp1 = sp0;
    SharedPointer<Test> sp2 = NULL;

    sp2 = sp1;  // 三个指针指向同一片空间

    sp2->value = 100;

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


    sp2.clear();
    cout << (sp0 == sp2) << endl;
    */

    /* 测试二: */
    const SharedPointer<Test> sp0 = new Test();
    sp0->value = 100;

    return 0;
}

猜你喜欢

转载自blog.csdn.net/dashuu/article/details/115219509