1 vs版本auto_ptr智能指针实现
vs版本auto_ptr智能指针解决了vc版的缺点,即智能指针通过拷贝或赋值转让空间后,不能再通过原来的智能指针去访问失去管理权的空间,在空间管理权所属方面与vc版不同的是,vs版的实现是通过使成员指针__Ptr为空表示失去空间管理权,而vc版的实现是通过成员_Owns为假时表示失去空间管理权。
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string>
#include <vld.h>
using namespace std;
template<class _Ty>
class AutoPtr
{
public:
AutoPtr(_Ty *p = 0):_Ptr(p){}
// 拷贝构造,通过_Y.Release对_Ptr赋值,保证_Y._Ptr在赋值后为空
// 即释放空间管理的权限
AutoPtr(AutoPtr<_Ty> &_Y):_Ptr(_Y.Release()){}
// 赋值语句
AutoPtr& operator=(AutoPtr<_Ty> &_Y)
{
if (this != &_Y)
{
// 通过Reset等价于完成了原来空间的释放及赋值新的空间
Reset(_Y.Release());
}
return *this;
}
~AutoPtr() { delete _Ptr; }
_Ty* get()const { return _Ptr; }
// 重载* 使对象有指针取*的特性
_Ty& operator*()
{
return *(get());
}
// 重载-> 使对象有指针 -> 运算的特性
_Ty* operator->()
{
return get();
}
// 空间管理权的释放,使自身的_Ptr为空,同时返回_Ptr
_Ty* Release()
{
_Ty* _tmp = _Ptr;
_Ptr = NULL;
return _tmp;
}
// 重设_Ptr的值为p
// 在重新设置前要保证原来的_Ptr的空间被释放
void Reset(_Ty *p)
{
if (p != _Ptr && _Ptr != 0)
delete _Ptr;
_Ptr = p;
}
private:
_Ty* _Ptr;
};
class Test
{
public:
void fun()
{
cout << "Test fun" << endl;
}
};
int main()
{
int *p1 = new int(10);
AutoPtr<int> ps1(p1);
cout << *ps1 << endl;
AutoPtr<int> ps2(ps1);
*ps2 = 100;
cout << *ps2 << endl;
// error,管理权以转移至ps2,不能再通过ps1访问原来空间,这是与vc版的不同之处
//cout << *ps1 << endl;
int *p2 = new int(20);
AutoPtr<int> ps3(p2);
ps3 = ps2;
cout << *ps3 << endl;
Test *q = new Test;
AutoPtr<Test> pt1(q);
pt1->fun();
AutoPtr<Test> pt2;
pt2 = pt1;
pt2->fun();
pt1->fun();
system("pause");
return 0;
}
2 auto_ptr智能指针的局限性
不管是vc版的auto_ptr智能指针,还是vs版的auto_ptr智能指针,都不能管理new出来的数据空间,因为内部实现释放空间时针对的都是delete,而不是delete[]。