zoukankan      html  css  js  c++  java
  • 利用模板和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;
    
    }
  • 相关阅读:
    减轻Temporal AA 的 拖影问题(ghosting)
    UE4开发PSVR游戏流程
    3.1 使用STC89C52控制MC20拨打电话
    2.6 基于ARDUINO UNO+MC20的路径显示功能
    2.5 使用ARDUINO做主控,手机发送短信控制开关LED
    2.4 使用ARDUINO控制MC20进行GPS数据的获取和解析
    2.3 使用ARDUINO控制MC20进行GPRS的TCP通讯
    2.2 使用ARDUINO控制MC20发短信
    2.1 使用ARDUINO控制MC20打电话
    1.8 使用电脑测试MC20的GPRS功能
  • 原文地址:https://www.cnblogs.com/wangkeqin/p/11225284.html
Copyright © 2011-2022 走看看