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

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

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

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

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

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

    AutoPtr(AutoPtr &ap)
        :_ptr(ap._ptr)
    {
        ap._ptr = NULL;   //管理权转移
    }
    AutoPtr& operator=(AutoPtr & 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 AutoPtr
{
public:
    AutoPtr(T *ptr)
        :_ptr(ptr)
        , _owner(true)
    {}
    ~AutoPtr()
    {
        if (_owner == true)
        {
            delete _ptr;
        }
    }
    AutoPtr( AutoPtr& ap)
        :_ptr(ap._ptr)
        , _owner(ap._owner)
    {
        ap._owner = false;
    }
    AutoPtr& operator=(AutoPtr& 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 ap1(new int(1));
    AutoPtr ap2(ap1);
    AutoPtr ap3(new int(2));
    ap3 = ap2;
}

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

template
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 &sp);
    ScopedPtr& operator=(ScopedPtr &sp);
protected:
    T *_ptr;
};

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

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

    SharedPtr& operator=(const SharedPtr& 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;
};