一、关于auto_ptr

C++11标准前STL中就有了auto_ptr, 是通过由 new 表达式获得的对象,并在 auto_ptr 自身被销毁时删除该对象的智能指针。它可用于为动态分配的对象提供异常安全、传递动态分配对象的所有权给函数和从函数返回动态分配的对象。


二、实现auto_ptr

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#include<iostream>
using namespace std;

namespace pzj
{
template<class _Ty>
class auto_ptr
{
private:
_Ty* _P; //new的对象的地址
bool owns; //拥有权(_P为NULL为假,反之)
public:
//成员函数
auto_ptr(_Ty* p = NULL) : _P(p), owns(p != NULL)
{}

/*
//存在浅拷贝的风险
auto_ptr(const auto_ptr& src):owns(src.owns), _P(src._P)
{
}
//存在形参拷贝构造资源转移,实参失效问题
auto_ptr(const auto_ptr& src):owns(src.owns), _P(src.release())
{
}
*/
~auto_ptr()
{
if (owns)
{
owns = false;
delete _P;
}
_P = NULL;
}
//转移所有权
auto_ptr& operator=(const auto_ptr& src)
{
if (owns)
{
delete get();
}
_P = src.release();
if (_P != NULL)
{
owns = true;
}
return *this;
}
//观察器
//获取_P
_Ty* get()const
{
return _P;
}
_Ty& operator*()
{
return *_P;
}
_Ty* operator->()
{
//return get();
return &**this;
}
//修改器
//替换被管理对象
void reset(_Ty* p = NULL)
{
if (owns)
{
delete get();
}
_P = p;
if (_P == NULL)
{
owns = false;
}
}
//释放被管理对象的所有权
_Ty* release()
{
_Ty* tmp = _P;
if (owns)
{
delete get();
owns = false;
}
return tmp;
}
};
}

三、auto_ptr被C++11弃用,C++17移除的原因

该智能指针已经暴露出以下缺点:

  1. 拷贝构造语义不明(两种拷贝构造都会带来风险:浅拷贝风险、实参失效问题)
  2. 赋值重载语义不明(转移资源or浅拷贝?)
  3. 未提出资源转移的问题(C11后提出 移动构造、移动赋值的概念)
  4. 未解决delete[]释放资源的问题