把指针交给对象处理,当程序结束时,对象会被自动调用析构,从而完成指针指向的动态内存的释放。
auto_ptr 就是完成动态内存的管理的 智能指针。
这个版本的auto_ptr 是一个类模板 ,有两个数据成员
bool _Owns 代表拥有权 多个指针可以指向同一块空间(浅拷贝)
但是保证只有一个指针 拥有拥有权.防止内存的多次释放
_Ty _Ptr 代表保存指针的指向,用来管理指针指向的内存空间
除了构造析构拷贝构造赋值方法以外
还要重载 指针的两个运算符 *和-> 用来模拟指针的操作。
#include<iostream>
using namespace std;
template <class _Ty>
class auto_ptr //有拥有权的成员
{
public:
auto_ptr(_Ty *_p = 0) :_Owns(_p != 0), _Ptr(_p) {}
auto_ptr(const auto_ptr<_Ty> &_Y) :_Owns(_Y._Owns), _Ptr(_Y.release())
{}//_Y把拥有权给出去之后,自己释放掉 并且让两个指针都指向同一空间
auto_ptr<_Ty> & operator =(const auto_ptr<_Ty>&_Y)
{
if (this != &_Y)//不是给自己赋值
{
if (_ptr != _Y._Ptr)//指向的不是同一块空间
{
if (_Owns)//如果自己有拥有权
delete _ptr; //释放掉
_Owns = _Y._Owns; //拿到赋值对象的拥有权
}
else if (_Y._Owns)//指向同一块空间 并且赋值对象有拥有权
{
_Owns = true;//夺走其拥有权
}
_ptr = _Y.release();//指向赋值对象的内存空间 并让赋值对象的拥有权变为0
}
return *this;
}
~auto_ptr()
{
if (_Owns) //如果有拥有权 就释放它
delete _Ptr;
}
_Ty * release()const
{
(const_cast<auto_ptr<_Ty>>*)(this)->_Owns = false;
return _ptr;
}
public:
_Ty &operator *()const
{
return *_Ptr;
}
_Ty *operator ->()const
{
return _Ptr;
}
private:
bool _Owns; //多个指针可以指向同一块空间 但是保证只有一个指针 拥有拥有权
_Ty *_Ptr;
};
int main()
{
int *p = new int(10);
auto_ptr<int> pa(p);
cout << *pa << endl;
}
这个版本的auto_ptr没有bool _Owns 这个数据成员
用函数实现 拥有权的转移 使得转移地更彻底,一旦拷贝构造或者赋值,旧的对象(智能指针)将不能使用
template <class _Ty>
class auto_ptr
{
auto_ptr(_Ty *_p = 0) :_Ptr(_p) {}
auto_ptr(auto_ptr<_Ty> &_Y) :_Ptr(_Y.release())
{}//_Y被赋空,此时只有 构造的新对象指向_Y原先指向的空间
auto_ptr<_Ty> &operator =(auto_ptr<_Ty> &_Y)
{
if (this != &_Y)
{
reset(_Y.release());
//把_Y赋空 并且让this 指向_Y的空间
}
return *this;
}
~auto_ptr()
{
delete _Ptr;
}
public:
_Ty &operator *()const
{
return *_Ptr;
}
_Ty *operator ->()const
{
return _Ptr;
}
_Ty *release()
{
_Ty *_Tmp = _Ptr;
_Ptr = NULL;
return _Tmp;
}
void reset(_Ty *_p = 0) //重新设置指向新的空间
{
if (_p != _Ptr&&_Ptr != NULL) //二者指向的空间不一样
{
delete _Ptr; //旧空间释放掉
}
_Ptr = _p; //指向新空间
}
private:
_Ty *_Ptr;
};