双管齐下——智能指针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; }

猜你喜欢

转载自www.cnblogs.com/single-dont/p/10423293.html