1.9、weak_ptr真的不计数?是否有计数方式,在哪分配的空间

std::weak_ptr本质上是不拥有对象所有权的智能指针,它不会增加对象的“强引用计数”(即shared_ptr的引用计数),因此不会直接影响对象的生命周期。但这并不意味着weak_ptr完全不计数,它确实维护了一个“弱引用计数”,用于跟踪当前有多少weak_ptr实例观察着同一个控制块(control block)。

控制块(Control Block)

shared_ptrweak_ptr共享一个控制块,这个控制块里包含两个计数器:

  • • 强引用计数(strong count):记录有多少shared_ptr实例拥有对象,决定对象的生存期。
  • • 弱引用计数(weak count):记录有多少weak_ptr实例观察该对象,控制控制块本身的生命周期。

对象销毁时机

当最后一个shared_ptr销毁时,强引用计数归零,对象被析构释放,但控制块不会立即销毁,必须等到所有weak_ptr也销毁(弱引用计数归零)后,控制块才会被释放。这意味着对象内存释放与控制块内存释放是两个阶段。

内存分配

控制块通常是动态分配的,且在make_shared的实现中,控制块和对象可能被分配在同一块内存中(内存共置),以提升性能和减少内存碎片。这也解释了为什么即使对象被销毁,若还有weak_ptr存在,内存不会完全释放。

为什么需要弱引用计数?

虽然weak_ptr不影响对象的生命周期,但它必须知道控制块何时可以安全销毁。弱引用计数确保控制块在所有shared_ptrweak_ptr都销毁后才释放,避免悬空指针和内存错误。

总结

特性 shared_ptr weak_ptr
是否拥有对象所有权 是,增加强引用计数 否,不增加强引用计数
是否维护计数 是,维护强引用计数和弱引用计数 是,维护弱引用计数
控制块生命周期 控制对象生命周期,控制块由弱引用计数控制 观察控制块,影响控制块释放时机
内存分配 控制块和对象通常动态分配,make_shared可共置 共享控制块,不单独分配内存

因此,weak_ptr“不计数”是指它不增加对象的强引用计数,不延长对象生命周期,但它确实维护弱引用计数,参与控制块的生命周期管理。
本文首发于【讳疾忌医-note】公众号,未经授权,不得转载。
(加入我的知识星球,免费获取账号,解锁所有文章。)

 

阅读剩余
THE END