利用模板和C++11特性实现的智能指针-作用同share_ptr

根据C++11特性实现,基本上实现了同SharePtr同样的功能,有时间继续优化。之前一直以为引用计数是一个静态的int类型,实际上静态值是不可以的。之前项目中总是不太习惯使用智能指针。通过自实现的方式,充分了解了智能指针的实现。

template <class T>
class SmartPtr
{
public:
    SmartPtr(T * pointee=NULL)
        :_pointee(pointee),_useCount(NULL){
        if(_pointee)
        {
            _useCount = new unsigned int(0);
            *_useCount = 1;
            cout<<"create a new smart pointer"<<endl;
        }
    }
    SmartPtr(T * pointee,const std::function<void(T*)> deleter)
        :_pointee(pointee),_useCount(NULL),_deleter(deleter){
        if(_pointee)
        {
            _useCount = new unsigned int(0);
            *_useCount = 1;
            cout<<"create a new smart pointer"<<endl;
        }
    }

    SmartPtr(const SmartPtr &another)
        :_pointee(NULL),_useCount(NULL)
    {
        if(another._useCount)
        {
            _useCount = another._useCount;
            (*_useCount)++;
            _pointee = another._pointee;
            if(another._deleter)
                _deleter = another._deleter;
        }
    }

    ~SmartPtr()
    {
        cout<<"SmartPtr delete"<<endl;
        if(_useCount){
            if(--(*_useCount) == 0){
                if(_deleter)
                    _deleter(_pointee);
                else
                    delete _pointee;
                delete _useCount;
            }
            _useCount = NULL;
            _pointee = NULL;
        }
    }
    SmartPtr &operator=(const SmartPtr &another)
    {
        if((this != &another) && (_useCount !=NULL || another._useCount!=NULL))
        {
            if(_useCount ==NULL && another._useCount!=NULL)
            {
                _useCount = another._useCount;
                ++(*_useCount);
                _pointee = another._pointee;
            }
            else if(_useCount !=NULL && another._useCount==NULL)
            {
                if(--(*_useCount) == 0){
                    if(_deleter){
                        _deleter(_pointee);
                    }
                    else
                        delete _pointee;
                    delete _useCount;
                }
                _pointee = NULL;
                _useCount = NULL;
            }
            else if(_useCount !=NULL && another._useCount!=NULL)
            {
                if(--(*_useCount) == 0){
                    if(_deleter)
                        _deleter(_pointee);
                    else
                        delete _pointee;
                    delete _useCount;
                }
                _useCount = another._useCount;
                ++(*_useCount);
                _pointee = another._pointee;
            }
        }
        return *this;

    }
    bool operator!() const
    {
        return !_pointee?true:false;
    }

    operator  void*(void) const
    {
        return _pointee;
    }

    T * operator->() const
    {
        return _pointee;
    }

    T & operator*() const
    {
        return *_pointee;
    }
    T * get()
    {
        return _pointee;
    }
    bool unique()
    {
        if(!_useCount)
            return false;
        return *_useCount==1?true:false;
    }
    constexpr long use_count() noexcept
    {
        if(!_useCount)
            return 0;
        return *_useCount;
    }
    //    void swap();
    void reset()
    {
        if(_useCount){
            if(--(*_useCount)==0)
            {
                if(_deleter){
                    _deleter();
                    memset(&_deleter,0x00,sizeof(decltype(_deleter)));
                }
                else
                    delete _pointee;
                delete _useCount;
            }
            _pointee = NULL;
            _useCount = NULL;

        }
    }
    void reset(T * pt)
    {
        if(--(*_useCount)==0)
        {
            if(_deleter){
                _deleter(_pointee);
                memset(&_deleter,0x00,sizeof(decltype(_deleter)));
                cout<<"memset _deleter"<<endl;
            }

            else{
                delete _pointee;
                cout<<"delete the number"<<endl;
            }
            *_useCount = 1;
        }
        else{
            _useCount = new unsigned int(1);

        }
        _pointee = pt;
    }

    void reset(T * pt,const std::function<void(T*)>& deleter)
    {
        if(--(*_useCount)==0)
        {
            if(_deleter)
                _deleter(_pointee);
            else
                delete _pointee;

            _deleter = deleter;
            *_useCount = 1;
        }
        else{
            _useCount = new unsigned int(1);

        }
        _pointee = pt;
    }

private:
    unsigned int *_useCount;
    T * _pointee;
    std::function<void(T*)> _deleter;
};


class Test
{
public:
    Test(){cout<<"Test()"<<endl;}
    Test(const Test &another){cout<<"Test(const Test &another)"<<endl;}
    Test & operator=(const Test &another){
        cout<<"Test & operator=(const Test &another)"<<endl;
        return *this;
    }
    ~Test(){
        cout<<"~Test()"<<endl;
    }
};

void funcdelet(Test *t)
{
    delete[] t;
    cout<<"costmos deleter"<<endl;
}
int main()
{
    //    SmartPtr<Test> pt1(new Test[10],[](Test *t){ delete[] t;cout<<"lamda function called"<<endl;});

    //    SmartPtr<Test> pt3(new Test,funcdelet);
    //    pt3 = pt1;

    SmartPtr<Test> pt2(new Test[10],[](Test *t){ cout<<"lamda function called"<<endl; delete[] t;});

    cout<<pt2.use_count()<<endl;

    pt2.reset(new Test,[](Test *t){delete t,cout<<"customs define"<<endl;});
    cout<<"------------------"<<endl;
    cout<<pt2.use_count()<<endl;

}
原文地址:https://www.cnblogs.com/wangkeqin/p/11225284.html