auto_ptr是当前C++标准库(STL)中提供的一种智能指针,包含于头文件 #include 。auto_ptr 能够方便的管理单个堆内存对象,在你不用的时候自动帮你释放内存。
一个版本的auto_ptr是Linux和VS中使用的,另一个是VC版本的,下面是VC版本的auto_ptr的源代码剖析:
template<class _Ty>
class auto_ptr
{
public:
explicit auto_ptr(_Ty *_P=0):_Owns(_P!=0),_Ptr(_P) //构造
{}
~auto_ptr() //析构
{
if (_Owns) //当拥有权限为真,delete指针所指向的内容
{
delete _Ptr;
}
}
auto_ptr(const auto_ptr<_Ty> &_Y):_Owns(_Y._Owns),_Ptr(_Y.release()) //拷贝构造
{}
auto_ptr<_Ty>& operator=(const auto_ptr<_Ty> &_Y) //拷贝赋值
{
//若pa2=pa1
if (this!=&_Y) //当两个对象不是自身复制
{
if (_Ptr!=_Y._Ptr) // 当pa2和pa1指向地址不同
{
if (_Owns) //pa2有指向,就析构pa2指向的内容
{
delete _Ptr;
}
_Owns = _Y._Owns; //将pa1的拥有权限转移到pa2
}
else if(_Y._Owns) //如果pa1和pa2指向地址相同,判断pa1是否有拥有权
{
_Owns = true; //如果pa1有拥有权,则pa2赋值为有拥有权
}
_Ptr = _Y.release(); //将pa1拥有权释放,并将pa1指针赋值给pa2
}
return *this; // 返回pa2
}
_Ty& operator*() const //重载*
{
return *_Ptr;
}
_Ty* operator->() const //重载->
{
return _Ptr;
}
_Ty* release() const //将拥有权限释放,并返回指针 //常对象只能调用常方法所以要加const
{
((auto_ptr<_Ty>*) this)->_Owns = false; //将拥有权限释放 //强制转换是为了让const失去作用,就是将const auto_ptr类型强转为auto_ptr类型,就可以修改_Y了,但出了这一步,_Y还是const的,_Y.Owns=0;就会报错
return _Ptr;
}
private:
bool _Owns; //加了mutable关键字,此变量就不受const的限制,但是不安全
_Ty *_Ptr;
};
当pa2 = pa1时 :
1.pa2 无指向 : 将pa1的指针给pa2赋值,再将pa1将拥有权进行转移;
2.pa2 有指向不同于pa1的对象 : 将pa2的指向进行析构,再将pa1的指针给pa2赋值,将pa1的拥有权转移;
3.pa2 有指向和pa1相同的对象 : 判断pa1是否有拥有权,有则将pa1的拥有权转移给pa2。
但vc版的auot_ptr也有一些问题,就是将拥有权转移后,除了不能够对其多次析构外,还可以对其进行操作,这就不好了,你都已经分手了,还不放手。在VS版本上对拥有权有更好的管理。
如果两个指针指向一个空间但是都没有拥有权,最后需要用delete释放。