[Cpp基础] [08] 动态内存与智能指针

Last Updated on 2020年4月14日

动态内存与智能指针

new+delete

  • new delete是C++中的两个主要的表达式.
    • new相当于C的malloc() + T(),delete相当于Cfree() + ~T().构造和析构总是会被调用.
    • operator new()以及operator delete()仅能用于覆盖内存分配操作,构造和析构的调用是无法被替换的.
  • delete能否正常执行依赖于指向的对象能否delete,而不依赖于指针自身(指针类型不含任何额外信息).
  • new T[n]中,n可以为0,返回的将是一个不能解引用的指针值,该指针值保证非nullptr,可以做正常的比较.
  • newdelete表达式总是会触发构造和析构,必要时可以使用malloc+placement new方案进行更精细的控制.
    • 不要使用自定义的allocator

shared_ptr与unique_ptr

  • 智能指针都不是为数组型数据设计的,所以都没有重载[],+,-等运算符.
    • T[n]型应该使用vector<T>
  • 智能指针主要包括sharedunique,二者服务于不同的设计场景.
    • 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()保证是线程安全的