模拟实现智能指针auto_ptr,scoped_ptr,shared_ptr

智能指针,顾名思义它是一个聪明的指针,那么到底聪明到哪了呢,让我们一起来看以下的代码。

void test1()   //内存泄露
{
    int *p = new int(1);
    if (1)
    {
        //...
        return;
    }
    //...
    //...
    delete p;
}

智能指针就是可以自动化地管理指针所指向的动态内存的释放。

  1. STL---AutoPtr (管理权转移,不推荐使用)包含在头文件 #include<memory>中。

新方案:(管理权转移)std::auto_ptr 能够方便的管理单个堆内存对象。

template<class T>
class AutoPtr  //管理权转移
{
public:
    AutoPtr(T *ptr)  
        :_ptr(ptr)
    {}
    ~AutoPtr()
    {
        if (_ptr == NULL)
        {
            cout << "delete:" << _ptr << endl;
            delete _ptr;
        }
    }

    AutoPtr(AutoPtr<T> &ap)
        :_ptr(ap._ptr)
    {
        ap._ptr = NULL;   //管理权转移
    }
    AutoPtr<T>& operator=(AutoPtr<T> & ap)
    {
        if (this != &ap)
        {
            delete _ptr;
            _ptr = ap._ptr;
            ap._ptr = NULL;
        }
        return *this;
    }
    T &operator*()
    {
        return *_ptr;
    }
    T *operator->()
    {
        return _ptr;
    }
protected:
    T *_ptr;
};

旧方案:(在某些情况下,会产生野指针)

思路:在新方案的基础上,新增一个bool变量(_owner),只要_owner为true,才析构,不再通过将赋值的值置空。

template<class T>
class AutoPtr
{
public:
    AutoPtr(T *ptr)
        :_ptr(ptr)
        , _owner(true)
    {}
    ~AutoPtr()
    {
        if (_owner == true)
        {
            delete _ptr;
        }
    }
    AutoPtr( AutoPtr<T>& ap)
        :_ptr(ap._ptr)
        , _owner(ap._owner)
    {
        ap._owner = false;
    }
    AutoPtr<T>& operator=(AutoPtr<T>& ap)
    {
        if (this != &ap)
        {
            delete _ptr;
            _ptr = ap._ptr;
            _owner = ap._owner;
            ap._owner = false;
        }
        return *this;
    }
protected:
    T *_ptr;
    bool _owner;
};
void test1()
{
    AutoPtr<int> ap1(new int(1));
    AutoPtr<int> ap2(ap1);
    AutoPtr<int> ap3(new int(2));
    ap3 = ap2;
}

2. boost―ScopedPtr(防拷贝。简单、粗暴,只定义,不实现)

template<class T>
class ScopedPtr   //必须需要的1.声明,2.保护类型
{
public:
    ScopedPtr(T *ptr)
        :_ptr(ptr)
    {}
    ~ScopedPtr()
    {
        if (_ptr == NULL)
        {
            delete _ptr;
        }
    }
    T & operator*()
    {
        return *_ptr;
    }
    T* operator->()
    {
        return _ptr;
    }
protected:  //protected:防止别人搞破坏行为
    ScopedPtr( ScopedPtr<T> &sp);
    ScopedPtr<T>& operator=(ScopedPtr<T> &sp);
protected:
    T *_ptr;
};

3. boost―SharedPtr(引用计数的方法实现)

template<class T>
class SharedPtr   //引用计数
{
public:
    SharedPtr(T *ptr)
        :_ptr(ptr)
        , _pcount(new int(1))
    {}
    ~SharedPtr()
    {
        if (--(*_pcount)==0)
        {
            delete _ptr;
            delete _pcount;
        }
    }
    SharedPtr(const SharedPtr<T> &sp)
        :_ptr(sp._ptr)
        , _pcount(sp._pcount)
    {
        ++(*_pcount);
    }

    SharedPtr<T>& operator=(const SharedPtr<T>& sp)
    {
        if (_ptr != sp._ptr) //防止自赋值和同时管理同一块空间
        {
            if (--(*_pcount) == 0)
            {
                delete _ptr;
                delete _pcount;
            }
            _ptr = sp._ptr;
            _pcount = sp._pcount;
            ++(*_pcount);
        }
        return *this;
    }
    T& operator*()
    {
        return *_ptr;
    }
    T* operator->()
    {
        return _ptr;
    }
protected:
    T *_ptr;
    int *_pcount;
};


你可能感兴趣的:(C++,智能指针)