关于智能指针
- 在C++11中通过引入智能指针的概念,使得C++程序员不需要手动释放内存
- 智能指针的种类
- std::unique_ptr (独占指针)
- std::shared_ptr (计数指针)
- std::weak_ptr (shared_ptr 的补充)
- 注意
- std::auto_ptr 已废弃
智能指针概述
C++的指针包括两种
- 原始指针 (raw pointer)
- 智能指针
智能指针是原始指针的封装,其优点是会自动分配内存,不用担心潜在的内存泄露
智能指针与原始指针
- 并不是所有的指针都可以封装成智能指针,很多时候原始指针要更方便
- 各种指针中,最常用的是裸指针,其次是unique_ptr和shared_ptr
- weak_ptr是share_ptr的一个补充应用场景较少
智能指针与Rust的内存安全
- 智能指针只解决一部分问题,即独占/共享所有权指针的释放、传输
- 智能指针没有从根本上解决C++内存安全问题,不加以注意依然会造成内存安全问题
独占指针: unique_ptr
- unique_ptr
- 在任何给定的时刻,只能有一个指针管理内存
- 当指针超出作用域时,内存自动释放
- 该类型指针不可Copy,只可以Move
创建方式
- 三种创建方式
- 通过已有的裸指针创建 (建议设置成空销毁掉)
- 通过new来创建 (与第一种没有区别)
- 通过std::make_unique创建 (推荐)
- unique_ptr可以通过get()获取地址
- unique_ptr实现->与*
- 可以通过->调用成员函数
- 可以通过*调用dereferencing
代码实现
1 | /************************************************************************* |
unique_ptr与函数调用
- unique_ptr是不可Copy,只可以Move
- 在做函数参数或是返回值中一定注意所有权
函数调用与unique_ptr注意事项
- Passing by value
- 需要用std::move来转移内存权限
- 如果参数值传入std::make_unique语句 自动转为move
- Passing by reference(传引用)
- 如果设置参数为const则不能改变指向
- 比如说reset()
- reset()方法为智能指针清空方法
- 如果设置参数为const则不能改变指向
- Return by value
- 指向一个local object
- 可以用作链式函数
计数指针: shared_ptr
Ps:看看析构几次!!!!!!!!!!!!!
销毁是按照内存来的、它数据只有一套只会销毁一次
shared_ptr计数指针又称共享指针
与unique_ptr不同的是它可以共享数据的
shared_ptr创建了一个计数器与类对象所指的内存相关联
Copy则计数器加一,销毁则计数器减一
api为use_count()
shared_ptr与函数
- shared_ptr passed by value
- copy
- 函数内部计数器加一
- shared_ptr passed by ref
- const表示不可改变指向
- retuming by value
- 链式调用
代码实现
1 | /************************************************************************* |
shared_ptr与unique_ptr
- 不能将shared_ptr转换为unique_ptr
- unique_ptr可以转换为shared_ptr
- 通过std::move
常见的设计模式
- 将你的函数返回unique_ptr是一种常见的设计模式,这样可以提高代码的复用度,你可以随时改变为shared_ptr
unique_ptr与shared_ptr代码实现
1 | /************************************************************************* |
weak_ptr(弱引用)
- weak-ptr并不拥有所有权
- 并不能调用->和解引用*
weak_ptr为什么会存在
- A类中有一个需求需要存储其他A类对象的信息
- 如果使用shared_ptr,那么在销毁时会遇到循环依赖问题(cyclic dependency problem)
- 所以我们这里需要用一个不需要拥有所有权的指针来标记该同类对象
- weak_ptr可以通过lock()函数来提升为shared_ptr(类型转换)
代码实现
1 | /************************************************************************* |