You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何unique_ptr需存储删除器却能实现无开销?

为什么unique_ptr存储删除器却能实现无开销?

这问题问到点子上了,咱们结合《C++ Primer》里的论述来拆解清楚:

《C++ Primer》16.1.6 效率与灵活性章节提到:我们可以确定shared_ptr不会将deleter作为直接成员存储,因为deleter的类型要到运行时才可知。而由于deleter的类型是unique_ptr类型的一部分,deleter成员的类型在编译时就已确定,因此deleter可以直接存储在每个unique_ptr对象中。

乍一看好像unique_ptr要存删除器,那怎么做到无开销?核心就藏在编译期类型确定这个关键特性里:

  • 用默认删除器时:编译器完全能把这个删除器的逻辑直接优化掉。因为默认删除器的行为是固定的(调用delete或delete[]),编译器不需要额外存储任何函数对象或指针,直接生成对应的销毁代码就行,相当于没这个“成员”一样。
  • 用自定义删除器时:由于删除器的类型已经是unique_ptr模板参数的一部分,编译器可以把删除器的逻辑直接内联到代码里。如果你的自定义删除器是空类(比如很多标记式的删除器),还能通过**空基类优化(EBO)**把这个“成员”的内存开销彻底抹掉——空类在C++里本身就不会占用额外空间,编译器直接把它的存在优化没了。

对比shared_ptr的情况就更明显了:shared_ptr的删除器类型是运行时动态确定的,它必须用函数指针或者虚表来间接调用删除器,这就必然带来额外的内存开销(比如多存一个指针)和运行时的间接调用成本。而unique_ptr因为编译期就把删除器的类型锁死了,编译器有足够的信息做极致优化,表面上存了删除器,实则很多时候根本没额外开销。

内容的提问来源于stack exchange,提问作者choxsword

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 08:23:13