文章目录
一、智能指针是什么?
<memory.h>
智能指针的行为类似常规指针,重要的区别是它负责自动释放所指向的对象。
标准库提供的两种智能指针的区别在于管理底层指针的方法不同
- shared_ptr允许多个指针指向同一个对象;
- unique_ptr则“独占”所指向的对象;
- weak_ptr的伴随类,它是一种弱引用,指向shared_ptr所管理的对象。
二、三类智能指针
1. shared_ptr
a. shared_ptr 和 unique_ptr 都支持的操作
shared_ptr<T> sp | 空智能指针,可以指向类型为T 的对象 |
p | 将 p 用作一个条件判断,若 p 指向一个对象,则为 true |
*p | 解引用 p ,获得它指向的对象 |
p->mem | 等价于 (*p).mem |
p.get() | 返回 p 中保存的指针。要小心使用,若智能指针释放了其对象向,返回的指针所指向的对象也就消失了 |
swap(p,q) p.swap(q) | 交换 p 和 q 中的指针 |
初始化与使用
- 默认初始化的智能指针中保存着一个空指针。
shared_ptr<string> p1;
shared_ptr<list<string>> p2;
- 使用
if (p1 && p1->empty())
*p1 = "hi";
b. shared_ptr 特有的操作
make_shared<T> | 返回一个 shared_ptr ,指向一个动态分配的类型为 T 的对象。使用 args 初始化此对象 |
shared_ptr<T>p(q) | p 是 shared_ptr q 的拷贝:此操作会递增 q 中的计数器。q 中的指针必须转换为 T* |
p=q | p 和 q 都是 shared_ptr ,所保存的指针必须能相互转换。此操作会递减 p 的引用计数,递增 q 的引用计数:若 p 的引用计数变为 0 ,则将其管理的原内存释放 |
p.unique() | 若p.use_count() 为1,返回 true ,否则返回 false |
p.use_count() | 返回与 p 共享对象的智能指针数量;可能很慢,主要用于调试 |
make_shared() 函数
make_shared用其参数来构造给定类型的对象,如果我们不传递任何参数,对象就会进行值初始化。
shared_ptr<int> p3 = make_shared<int>(42);
shared_ptr<string> p4 = make_shared<string>(10,'9');
shared_ptr<int> p5 = make_shared<int>();
拷贝和赋值
每个 shared_ptr 都会记录有多少个其他 shared_ptr 指向相同的对象,称为 引用计数
。当一个对象的引用计数为 0 时,该对象会被释放。
- 拷贝,引用计数递增。
- 赋值或销毁,引用计数递减。
auto p = make_shared<int>(42); // 赋值
auto q(p); // 拷贝
auto r = make_shared<int>(42);//r指向的int只有一个引用者
r=q;//给r赋值,令它指向另一个地址
//递增q指向的对象的引用计数
//递减r原来指向的对象的引用计数
//r原来指向的对象已没有引用者,会自动释放
自动销毁所管理的对象
当指向一个对象的最后一个shared_ptr被销毁时,shared_ptr类会自动销毁此对象,它是通过另一个特殊的成员函数-析构函数完成销毁工作的,类似于构造函数,每个类都有一个析构函数。析构函数控制对象销毁时做什么操作。析构函数一般用来释放对象所分配的资源。shared_ptr的析构函数会递减它所指向的对象的引用计数。如果引用计数变为0,shared_ptr的析构函数就会销毁对象,并释放它所占用的内存。
自动释放相关的内存
当动态对象不再被使用时,shared_ptr类还会自动释放动态对象,这一特性使得动态内存的使用变得非常容易。如果你将shared_ptr存放于一个容器中,而后不再需要全部元素,而只使用其中一部分,要记得用erase删除不再需要的那些元素。
定义和改变 shared_ptr 的方法
shared_ptr<T> p(q) | |
shared_ptr<T> p(u) | |
shared_ptr<T> p(q,d) | |
p.reset() | |
p.reset(q) | |
p.reset(q,d) |
shared_ptr 和 new 结合使用
/* 误:内置指针隐式转换为智能指针 */
shared_ptr<int> p1 = new int(1024);
/* 正:直接初始化 */
shared_ptr<int> p2(new int(1024))
2. unique_ptr
代码如下(示例):
data = pd.read_csv(
'https://labfile.oss.aliyuncs.com/courses/1283/adult.data.csv')
print(data.head())
该处使用的url网络请求的数据。