シミュレーションによるスマートポインタauto_ptr,scoped_ptr,shared_ptr


スマートポインタは、その名の通り賢いポインタですが、いったいどこまで賢いのか、以下のコードを見てみましょう.
void test1()   //    
{
    int *p = new int(1);
    if (1)
    {
        //...
        return;
    }
    //...
    //...
    delete p;
}

インテリジェントポインタとは、ポインタが指すダイナミックメモリの解放を自動的に管理することです.
  • STL-AutoPtr(管理権移転、使用推奨なし)はヘッダファイルincludeに含まれます.
  • 新しいシナリオ:(管理権移行)、std::auto_ptrは、単一のスタックメモリオブジェクトを容易に管理できます.
    template
    class AutoPtr  //     
    {
    public:
        AutoPtr(T *ptr)  
            :_ptr(ptr)
        {}
        ~AutoPtr()
        {
            if (_ptr == NULL)
            {
                cout < &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;
    };