- 目前我们使用的对象都是语言本身代替我们管理其生命周期和作用域,例如global object、局部的自动变量和局部的static变量,除此之外,语言也允许我们创建动态分配的对象(即运行时创建的对象):
- 不同类型的对象,其所在内存区域也有差别。目前为止有三种内存区域:
static
内存、stack
内存和heap
内存: - C++中的动态内存管理通过两个操作符进行:
new
和delete
: - 新标准通过头文件
memory
定义了三个智能指针:shared_ptr
,unique_ptr
和weak_ptr
,它们和普通指针的使用方式差不多,唯一的例外就是它们能够自动管理动态内存: - 创建
shared_ptr
指向的对象的安全方式: - 计数指针的拷贝和赋值,优雅之处在于
reference count
: - 所以计数指针是如何管理其动态分配的对象呢->
destructor
: - 因为计数指针保证只要有一个计数指针存在,其指向的对象就不会被释放。所以对于不再使用的计数指针,需要及时删除掉以避免浪费内存:
- 使用动态内存的三种情况:
- 多个对象共享潜在数据的场景很多吗?是不是有点像多个指针指向一个对象:
- 对于手动管理动态内存的
class
需要自己重写copy
、assign
和destructor
函数: delete
表达式遇到非动态内存的指针也是要命:- 使用原生指针管理动态内存的一些问题(忘记释放造成内存泄漏、多个指针指向同一个对象,只管理其中一个指针造成其他指针是悬挂指针、以及多次释放同一个动态内存对象):
- 计数指针的初始化方式多样,例如可以使用
new
进行,但要注意形式: - 智能指针不限于管理动态内存,也可以管理其他“资源”,对其进行善后处理:,例如关闭打开的连接:
- 原生指针和智能指针不能混用,否则计数器会失效:,具体而言:
- 类似于assign作用的
reset
成员: - 水能载舟,亦能覆舟:
- 独占指针:,其不支持copy和assign:
- 独占指针特有的
release()
成员: - 独占指针允许在指针将要被释放时进行拷贝/赋值:
weak_ptr
好弱,没有话语权:- 因为
weak_ptr
指向的对象随时会被销毁,所以需要谨慎的访问其所指向的对象: - 动态分配数组的两种方式:
new int []
和allocator
,对于涉及动态分配数组的类而言,需要我们手动定义copy
、assign
和destructor
: - 注意动态分配的数组返回的是指向数组中第一个元素类型的指针:
- 与
new type[size]
相对应的delete [] pointer
: - 智能指针和动态数组搭配:
- 使用
allocator
将内存分配和对象初始化分开: