您的位置:首页 > 编程语言 > C语言/C++

【C++】智能指针auto_ptr

2015-08-16 11:33 281 查看
C++的auto_ptr所做的事情,就是动态分配对象以及当对象不再需要时自动执行清理,使用std::auto_ptr,要#include <memory>。

实现代码如下:

#include <iostream>
#include <vld.h>
using namespace std;

//#define _THROW0()	throw ()抛出全部异常

template<class _Ty>
class auto_ptr
{
public:
//typedef _Ty element_type;
explicit auto_ptr(_Ty *_P = 0) _THROW0()
: _Owns(_P != 0), _Ptr(_P) {}
//explicit用来防止由构造函数定义的隐式转换
auto_ptr(const auto_ptr<_Ty>& _Y) _THROW0()
: _Owns(_Y._Owns), _Ptr(_Y.release()) {}
auto_ptr<_Ty>& operator=(const auto_ptr<_Ty>& _Y) _THROW0()
{
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;
}
}
_Ty& operator*() const _THROW0()
{
return (*get());
//return (*_Ptr);
}
_Ty *operator->() const _THROW0()
{
return (get());
//return (_Ptr);
}
_Ty *get() const _THROW0()
{
return (_Ptr);
}
_Ty *release() const _THROW0()
{
((auto_ptr<_Ty> *)this)->_Owns = false;
return (_Ptr);
}
private:
bool _Owns;
_Ty *_Ptr;
};

class Test
{
public:
void Print() const
{
cout << "this is test!"<< endl;
}
};


本文中重点谈论关于其的三个问题:

问题一:箭头操作符

测试代码为:

<span style="font-size:18px;"><strong>void main()
{
Test *pt = new Test;
auto_ptr<Test> pa(pt);
pa->Print();
}</strong></span>


为何使用pa->Print()而不是pa->->Print()?


箭头操作符看起来像二元操作符:接受一个对象和一个成员名,实际上,箭头操作符的右操作符并不是一个表达式,而是类成员的标识符,编译器自动将一个标识符传递给函数以获取类成员的工作。首先pa是对象,而且有operator->,调用之,返回_Ty*(Test*),为指针接下来就是调用Test的成员函数Print()。



问题二:

<span style="font-size:18px;"><strong>void main()
{
int *p = new int(10);
auto_ptr<int> pa(p);
auto_ptr<int> pb(pa);

cout << *pb << endl;
//cout << *pa << endl;
}</strong></span>


在原始的auto_ptr实现中被注释行可以实现,这是VC库的一个缺陷,修改release()函数后代码如下:

<span style="font-size:18px;"><strong>#include <iostream>
#include <vld.h>
using namespace std;

//#define _THROW0()	throw ()抛出全部异常

template<class _Ty>
class auto_ptr
{
public:
//typedef _Ty element_type;
explicit auto_ptr(_Ty *_P = 0) _THROW0()
: _Owns(_P != 0), _Ptr(_P) {}
//explicit用来防止由构造函数定义的隐式转换
auto_ptr(const auto_ptr<_Ty>& _Y) _THROW0()
: _Owns(_Y._Owns), _Ptr(_Y.release()) {}
auto_ptr<_Ty>& operator=(const auto_ptr<_Ty>& _Y) _THROW0()
{
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;
}
}
_Ty& operator*() const _THROW0()
{
return (*get());
//return (*_Ptr);
}
_Ty *operator->() const _THROW0()
{
return (get());
//return (_Ptr);
}
_Ty *get() const _THROW0()
{
return (_Ptr);
}
_Ty *release() const _THROW0()
{
_Ty *_newPtr = _Ptr;
((auto_ptr<_Ty> *)this)->_Owns = false;
((auto_ptr<_Ty> *)this)->_Ptr = 0;
return (_newPtr);
}
private:
bool _Owns;
_Ty *_Ptr;
};

class Test
{
public:
void Print() const
{
cout << "this is test!"<< endl;
}
};</strong></span>


此时被注释行无法执行。


问题三:以上auto_ptr无法实现数组的应用

修改代码及测试如下:

<span style="font-size:18px;"><strong>#include <iostream>
#include <vld.h>
using namespace std;

#define N 10

//#define _THROW0()	throw ()抛出全部异常

template<class _Ty>
class auto_ptr
{
public:
//typedef _Ty element_type;
explicit auto_ptr(_Ty *_P = 0) _THROW0()
: _Owns(_P != 0), _Ptr(_P) {}
//explicit用来防止由构造函数定义的隐式转换
auto_ptr(const auto_ptr<_Ty>& _Y) _THROW0()
: _Owns(_Y._Owns), _Ptr(_Y.release()) {}
auto_ptr<_Ty>& operator=(const auto_ptr<_Ty>& _Y) _THROW0()
{
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;
}
}
_Ty& operator[](int index) const
{
return *(get()+index);
//return *(_Ptr+index);
}
_Ty *get() const _THROW0()
{
return (_Ptr);
}
_Ty *release() const _THROW0()
{
_Ty *_newPtr = _Ptr;
((auto_ptr<_Ty> *)this)->_Owns = false;
((auto_ptr<_Ty> *)this)->_Ptr = 0;
return (_newPtr);
}
private:
bool _Owns;
_Ty *_Ptr;
};

void main()
{
int *p = new int
;
for(int i = 0; i < N; ++i)
{
p[i] = 0;
}
auto_ptr<int> pa(p);
auto_ptr<int> pb(p);
pb = pa;
for(i = 0; i < N; ++i)
{
cout << pb[i] << " ";
}
cout << endl;
}</strong></span>


以上代码如有不足之处请大家指出,谢谢大家~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: