zoukankan      html  css  js  c++  java
  • 双管齐下——智能指针auto_ptr

    在这里我们讨论的是auto_ptr。在这里我们可以用两个词来表示vc版和vs版的不同:

    藕断丝连(vs版:一个对象对一个空间没有操作权限后,但是还可以访问此空间的数据)。

    一刀两断(vs版:一个指针在将自己所指向的空间转接其他指针后,则自己就释放了,不能再通过此指针访问数据)。

    vc版:

    智能指针对象需要包含两个成员:权限标注、指针。

    template<class _Ty>
    class auto_ptr
    {
    public:
        explicit auto_ptr(_Ty *_P = 0) : _Owns(_P != 0), _Ptr(_P)
        {}
        //auto_ptr<int> pa1 = pa;
        auto_ptr(const auto_ptr<_Ty> &_Y) :_Owns(_Y._Owns), _Ptr(_Y.release())
        {
            //  ((auto_ptr<_Ty>*)(&_Y))->_Owns=false;
        }
        //auto_ptr<int> pa1;
        //pa1 = pa;
        auto_ptr<_Ty>& operator=(const auto_ptr<_Ty> &_Y)
        {
            if (this != &_Y)  //判断本类实例(this)与传入参数实例地址是否相同
            {
                //两种方法:①判断实例的数据成员 ②判断实例对空间的拥有权
                if (_Ptr != _Y._Ptr)  //方法①:判断本类实例成员_Ptr与传入参数实例成员_Ptr是否相同
                {
                    if (_Owns)   //根据拥有权来确定是否释放本类实例成员空间
                        delete _Ptr;
                    _Owns = _Y._Owns;  //拥有权转接
                }
                else if (_Y._Owns)//方法②
                    _Owns = true;
                _Ptr = _Y.release();
            }
            return (*this);
        }
        ~auto_ptr()
        {
            if (_Owns)
                delete _Ptr;
        }
    public:
        _Ty& operator*()const
        {
            return *_Ptr;
        }
        _Ty* operator->()const
        {
            return _Ptr;
        }
        _Ty *release() const
        {
            ((auto_ptr<_Ty> *)this)->_Owns = false;  //在此如果有园客疑惑const修饰后为什么还可以对数据成员进行修改,请参考本人上一篇博文。return (_Ptr);
        }
    private:
        bool _Owns;
        _Ty *_Ptr;
    };
    
    void main()
    {
        int *p = new int(10);
        auto_ptr<int> pa(p);
        cout << *pa << endl;
    
        auto_ptr<int> pa1 = pa;
        auto_ptr<int> pa2;
        pa2 = pa1;
    }

    vs版:

    智能指针auto_ptr只有一个成员:指针

    template<class _Ty> class auto_ptr;
    template<class _Ty>
    struct auto_ptr_ref
    {
        explicit auto_ptr_ref(_Ty *_Right) :_Ref(_Right){}
        _Ty *_Ref;
    };
    template<class _Ty>
    class auto_ptr
    {
    public:
        typedef auto_ptr<_Ty> _Myt;
        typedef _Ty element_type;
        explicit auto_ptr(_Ty * _Ptr=0):_Myptr(_Ptr){} //构造函数
        auto_ptr(_Myt& _Right)//拷贝构造函数
        {
            _Ty *Tmp = _Right._Myptr;
            _Right._Myptr = 0;//将原本自身置空
            _Myptr = Tmp;
        }
        auto_ptr(auto_ptr_ref<_Ty> _Right) //构造auto_ptr_ref的对象替换原有对象
        {
            _Ty *_Ptr = _Right._Ref;
            _Right._Ref = 0;
            _Myptr = _Ptr;
        }
        _Myt& operator=(_Myt& _Right) //重载=函数
        {
            reset(_Right.release());
            return (*this);
        }
        
        ~auto_ptr() //析构函数
        {
            delete _Myptr;
        }
    public:
        void reset(_Ty *_Ptr=0) //重置函数
        {
            if (_Ptr != _Myptr)
                delete _Myptr;
            _Myptr = _Ptr;
        }
        _Ty *release() //_Right.release() 释放函数
        {
            _Ty *_Tmp =_Myptr;
            _Myptr = 0;//将原本自身置空
            return (_Tmp);
        }
        _Ty& operator*()const
        {
            return *_Myptr;
        }
        _Ty* operator->()const
        {
            return _Myptr;
        }
    private:
        _Ty *_Myptr;
    };
    
    void main()
    {
        int *p = new int(10);
        auto_ptr<int> p1(p);

      //拷贝构造 auto_ptr
    <int>p2 = p1; cout << *p2 << endl;

      //重载= auto_ptr
    <int>p3; p3 = p2; cout << *p3 << endl;

      //以auto_ptr_ref的对象构造auto_ptr的对象 auto_ptr_ref
    <int> a1(p); auto_ptr<int>a2(a1); cout << *a2 << endl; }
  • 相关阅读:
    logback配置和使用
    安装多个jdk导致eclipse打不开问题
    Spring事务管理
    使用JavaConfig配置SpringMVC
    Spring pom.xml配置
    Maven私服搭建(Nexus Repository Manager 3)
    Maven多环境配置
    Maven多模块构建实例
    Maven依赖机制
    Maven安装与配置
  • 原文地址:https://www.cnblogs.com/single-dont/p/10423293.html
Copyright © 2011-2022 走看看