#include<iostream>
//#include<memory>
using namespace std;
//RAII 机制
template<class _Ty>
class auto_ptr
{
public:
explicit auto_ptr(_Ty *_P=0):_Owns(_P!=0),_Ptr(_P) //_Owns初始化为假
{}
auto_ptr(const auto_ptr<_Ty> &_Y):
_Owns(_Y._Owns),_Ptr(_Y.release())
{}
auto_ptr<_Ty>& operator=(const auto_ptr<_Ty> &_Y)
{
if(this != &_Y)
{
if(_Ptr != _Y.get())
{
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*release(const auto_ptr<_Ty> *const this)
_Ty* release()const
{
((auto_ptr<_Ty> * )this)->_Owns = false;
return _Ptr;
}
_Ty& operator*()const
{
return (*get());
}
_Ty* operator->()const
{
return(get());
}
_Ty* get()const
{
return _Ptr;
}
private:
bool _Owns; //是否对内存进行释放 真-->释放; 假-->不调用析构
_Ty *_Ptr;
};
void main()
{
int *p = new int(10);
auto_ptr<int> pa(p);
auto_ptr<int> pa1;
pa1 = pa;
auto_ptr<int> pa3(new int(12));
cout<<*pa<<endl;
cout<<*pa1<<endl;
cout<<*pa3<<endl;
}
auto_ptr的分析:
1.不可以用赋值初始化对象,auto_ptr的构造函数带explicit关键字,不能进行隐式转换。
auto_ptr<int> pa(new int(10));//OK
auto_ptr<int> pa = new int(10);//error
2.auto_ptr不用显示地使用delete释放内存。编译器会私下调用析构函数。auto_ptr在其析构函数里释放了动态开辟的空间。
3.拥有权转移--在拷贝构造或赋值函数中,释放掉pb对象原先指针,当赋值之后,pa不再绑定对象,也不再拥有对原先内存的管理权。pb置为pa所指内存区域。
auto_ptr对象对内存的拥有权是独享的。
auto_ptr<int> pb(pa);
auto_ptr<int> pb; pb = pa;
4.不能使用auto_ptr对象保存动态开辟数组的指针。 因为其析构函数里 是delete _Ptr; 而不是delete []_Ptr;
5.不能将auto_ptr对象储存在容器中。因为auto_ptr对象对内存的独享权。 容器的对象拷贝构造或赋值之后,两个对象都指向统一内存,值相等。