Last Updated on 2022年9月28日
动态内存与智能指针
new+delete
new delete
是C++中的两个主要的表达式.new
相当于C的malloc() + T()
,delete
相当于C
的free() + ~T()
.operator new()
以及operator delete()
仅能用于覆盖内存分配操作,构造和析构的调用是无法被替换的.
delete
能否正常执行依赖于指向的对象能否delete
,而不依赖于指针自身(指针类型不含任何额外信息).new T[n]
中,n可以为0,返回的将是一个不能解引用的指针值,该指针值保证非nullptr,可以做正常的比较.new
和delete
表达式总是会触发构造和析构,必要时可以使用malloc
+placement new
方案进行更精细的控制.placement new
仅仅用于在特定地址上触发构造函数, 后续需要手动调用析构函数来销毁对象.
shared_ptr与unique_ptr
- 智能指针都不是为数组型数据设计的,所以都没有重载
[],+,-
等运算符.T[n]
型应该使用vector<T>
- 智能指针主要包括
shared
和unique
,二者服务于不同的设计场景.shared_ptr
的自动释放由引用计数器实现.
- 注意,对于
shared_ptr
对象不是线程安全的, 多线程环境下需要加锁保护shared_ptr
对象. - 智能指针默认的销毁操作是
delete
,但是我们也可以手动控制智能指针的销毁操作,从而实现一些类似Guard的工具.
关于weak_ptr
weak_ptr
是一种访问shared_ptr
存的工具.其作用主要是实现更为灵活的资源管理.lock()
成员会返回一个shared_ptr
,它尝试持有资源,如果资源存在,则shared_ptr
非空.
- 例子:假设现在有一个缓存池.仅有一个管理线程管理资源,它负责控制
shared_ptr
对象的寿命, 其余线程则仅持有weak_ptr
来访问缓存池.- 对工作线程,如果调用
auto sp=weakp.lock()
时sp
非空,说明资源仍在缓存池中,可以正常使用,在使用完成后,销毁sp
即可. - 如果调用
auto sp=weakp.lock()
时sp
为空,那么说明资源被管理线程释放了,应当通知管理线程再次载入,然后再进一步操作. lock()
保证是线程安全的
- 对工作线程,如果调用