Skip to content

Commit 1ea8126

Browse files
Create "C++ 智能指针", Finished unique_ptr Part
1 parent bf18961 commit 1ea8126

File tree

1 file changed

+82
-0
lines changed

1 file changed

+82
-0
lines changed
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
---
2+
title: C++ 智能指针
3+
date: 2024-12-17 15:10:00 +0800
4+
categories: [笔记, C++]
5+
tags: [C++, 智能指针]
6+
---
7+
8+
## 指针
9+
10+
**普通的指针**: 指向某个内存区域的地址变量
11+
12+
- 如果一个指针指向的内存是动态分配的, 那么即使这个指针离开了所在的作用域, 这块内存也不会被自动释放, 从而导致**内存泄漏**.
13+
- 如果一个指针指向的是一个已经被释放的内存区域, 那么这个指针就是一个**悬空指针**, 使用悬空指针会导致不可预知的错误.
14+
- 如果定义了一个指针却没有初始化, 那么这个指针就是一个**野指针**, 使用野指针访问内存一般会造成`segmentation fault`报错.
15+
16+
```cpp
17+
int *p = new int(10); // 动态分配内存
18+
delete p; // 释放内存
19+
p = nullptr; // 防止成为悬空指针
20+
```
21+
22+
## 智能指针
23+
24+
智能指针是一个封装了动态对象的类对象, 离开作用域后会自动销毁, 销毁过程会调用析构函数来删除所封装的对象.
25+
26+
在标准模板库中, 提供了三种智能指针: `std::unique_ptr`, `std::shared_ptr`, `std::weak_ptr`.
27+
28+
### unique_ptr
29+
30+
```cpp
31+
template <
32+
class T, // T是所封装的动态分配的对象的类型
33+
class Deleter = std::default_delete<T> // 释放它所封装的对象时使用的方法
34+
> class unique_ptr;
35+
```
36+
37+
`unique_ptr`还有一个针对动态数组的版本`std::unique_ptr<T[]>`.
38+
39+
```cpp
40+
template <
41+
class T,
42+
class Deleter
43+
> class unique_ptr<T[], Deleter>;
44+
```
45+
46+
`unique_ptr`的常用函数:
47+
48+
- `T* get()`: 获得所管理对象的指针
49+
- `T* operator->()`: 调用了`get()`函数, 返回所管理对象的指针, 这样可以使用`->`操作符来访问所管理对象的成员
50+
- `T& operator*()`: 返回所管理对象的引用, 相当于`*get()`
51+
- `T* release()`: 接触对所封装对象的管理, 返回对象的指针, 之后该指针就脱离了`unique_ptr`的管理, 需要主动释放
52+
- `void reset(T* newObject);`: 删除掉原有的对象, 接管新的对象
53+
- `void swap(unique_ptr<T>& other);`: 与其他`unique_ptr`交换所管理的对象
54+
55+
`unique_ptr`与它所管理的动态对象是一对一的关系, 也就是不能有两个`unique_ptr`对象指向同一个地址
56+
57+
创建一个`unique_ptr`对象的方法是:
58+
59+
```cpp
60+
unique_ptr<A> ptr1(new A(参数));
61+
```
62+
63+
```cpp
64+
unique_ptr<A> ptr1 = make_unique<A>(参数);
65+
```
66+
67+
由于`unique_ptr`的特殊性, 不能被拷贝:
68+
69+
```cpp
70+
unique_ptr<T> p2 = p1; // 编译报错, unique_ptr类中删除了拷贝构造函数
71+
```
72+
73+
但是可以用`move()`函数进行控制权转移:
74+
75+
```cpp
76+
unique_ptr<T> p2 = move(p1); // 此后, p1只包含了一个空指针, p2拥有原来p1的指针的控制权
77+
cout << p1 << endl; // 这里可能出现`segmentation fault`报错, 因为p1是空指针
78+
```
79+
80+
### shared_ptr
81+
82+
### weak_ptr

0 commit comments

Comments
 (0)