智能指针的原理:
1. RAII特性
2. 重载operator*和opertaor->,具有像指针一样的行为。
RAII,也称为“资源获取就是初始化”,是C++等编程语言常用的管理资源、避免内存泄露的方法。它保证在任何情况下,使用对象时先构造对象,最后析构对象。
auto_ptr的一些特点:
当auto_ptr对象的生命周期结束时,析构函数会使用delete操作符自动销毁所保存的指针对象
auto_ptr可以转让所有权
在 STL 容器中使用auto_ptr存在重大风险,因为容器内的元素必需支持可复制(copy constructable)和可赋值(assignable),STL容器中的元素经常要支持拷贝,赋值等操作,在这过程中auto_ptr会传递所有权
VC下auto_ptr实现
namespace yxy
{
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())
{}
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& operator*()
{
return *_Ptr;
}
_Ty* operator->()
{
return _Ptr;
}
//_Ty* release(const auto_ptr<_Ty> * const this) 有const相当于前面多加了一个*,表示this指针指向的空间不可修改
_Ty* release()const
{
((auto_ptr<_Ty> *const)this)->_Owns = false;
//_Owns = false;
return _Ptr;
}
private:
bool _Owns; //mutable
_Ty* _Ptr;
};
};
VS下auto_ptr实现
namespace yxy
{
template<class _Ty>
class auto_ptr
{
typedef auto_ptr<_Ty> _Myt;
public:
auto_ptr(_Ty* _Ptr = 0) : _Myptr(_Ptr)
{}
auto_ptr(_Myt& _Right) : _Myptr(_Right.release())
{}
_Myt& operator=(_Myt& _Right) //赋值
{
reset(_Right.release());
return (*this);
}
~auto_ptr()
{
delete _Myptr; //nullptr
}
public:
_Ty* operator->() const
{
return (get());
}
_Ty& operator*() const
{
return (*get());
}
_Ty* get() const
{
return (_Myptr);
}
_Ty* release()
{
_Ty* _Tmp = _Myptr; //先存起来
_Myptr = 0; //再释放拥有权
return _Tmp;
}
void reset(_Ty* _Ptr = 0)
{
if (_Ptr != _Myptr)
delete _Myptr;
_Myptr = _Ptr;
}
private:
_Ty* _Myptr;
};
};
void main()
{
int* ptr = new int(10);
bit::auto_ptr<int> pa1(ptr);
cout << *pa1 << endl;
bit::auto_ptr<int> pa2;
pa2 = pa1;
//cout<<*pa1<<endl;
void main()
{
int* ptr = new int(10);
bit::auto_ptr<int> pa1(ptr);
cout << *pa1 << endl;
int* ptr1 = new int(20);
pa1.reset(ptr);
}
}