实现要点

  • 每个 unique_ptr 都独占其所管理的对象,因此无法被复制,应当删除其拷贝构造函数和赋值运算符。
  • 使用移动构造函数或移动赋值运算时,要将被移动的对象的底层指针置空。
  • 重载解引用 * 和箭头 -> 运算符,实现类似普通指针的调用
  • 使用RAII机制自动释放资源

代码:

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
template <typename T>
class UniquePtr
{
private:
T *ptr;

UniquePtr(const UniquePtr<T> &other) = delete;
UniquePtr<T> operator=(const UniquePtr<T> &other) = delete;

public:
explicit UniquePtr(T *p = nullptr) : ptr(p)
{
}

UniquePtr(UniquePtr<T> &&other)
{
ptr = other.ptr;
other.ptr = nullptr;
}

UniquePtr<T> &operator=(UniquePtr<T> &&other)
{
if (ptr != other.ptr)
{
delete ptr;
ptr = other.ptr;
other.ptr = nullptr;
}
}

T &operator*()
{
return *ptr;
}

T *operator->()
{
return ptr;
}

T *get()
{
return ptr;
}

void reset(T *p = nullptr) noexcept
{
delete ptr;
ptr = p;
}

T *release() noexcept
{
T *p = ptr;
ptr = nullptr;
return p;
}

void swap(UniquePtr<T> &other) noexcept
{
std::swap(ptr, other.ptr);
}

~UniquePtr()
{
delete ptr;
}
};