[我最近遇到了一个问题,即unique_ptr
和shared_ptr
都不是正确的解决方案。因此,我正在考虑发明另一种智能ptr(如下所述),但我心想:“我当然不是第一个想要此功能的人。”
所以我的高级问题是:
std::
功能)完成此操作,也许我遗漏了某些东西?需求:
unique_ptr
shared_ptr
的行为不同)。weak_ptr
,但要与单一所有权模型一起使用。激励示例:
假设我正在迭代接口指针的列表,并在它们上调用方法。其中一些方法可能导致列表中后面的项目被删除。
使用普通指针,我将获得那些已删除项目的悬挂引用。
拟议设计:
让我们调用拥有指针my_ptr
和非拥有引用my_weak_ptr
。
对于给定的对象,我们可能会有这样的图:
______
my_ptr<Obj> owner ---------> |Obj* | -------> [Obj data ... ]
+----> |count|
| +--> |_____|
my_weak_ptr<Obj> A ---+ |
|
my_weak_ptr<Obj> B -----+
my_ptr
将具有与unique_ptr
大致相同的接口。在内部,它将存储指向“控制块”的指针,该指针实际上只是“真实”指针和控制块本身的引用计数。销毁时,my_ptr
会将控制块指针设置为NULL并减少引用计数(并在适当的情况下删除控制块)。
my_weak_ptr
将是可复制的,并且具有某些get()
方法,该方法将返回真实的Obj*
。用户将负责在使用它之前检查它是否为NULL。销毁时,my_weak_ptr
将减少计数(并在适当的情况下删除控制块)。
缺点是每次访问都会在内存中进行两次跳跃。对于my_ptr
,也可以通过在内部存储真实的Obj*
来缓解这种情况,但是my_weak_ptr
引用将始终必须支付该双跳费用。
编辑:一些相关问题,来自给出的链接:
因此似乎需要这样的东西,但没有灌篮解决方案。如果需要线程安全,则shared_ptr
和weak_ptr
是正确的选择,但如果不是,它们会增加不必要的开销。
也有boost::local_scoped_ptr
,但它仍然是共享所有权模型;我宁愿阻止拥有指针的副本,例如boost::local_scoped_ptr
。
上面的评论中进行了很好的讨论,所以我将尝试回答我自己的问题并进行总结:
的确,这不是新领域。在随后的研究中,我发现了这种想法的各种形式:
unique_ptr
WeakPtr
方法,文档说:“如果从其他位置销毁了所引用的对象,则弱指针将神奇地变为空。”lock()
T
,但解决了类似的问题。还有一些更接近trackable<T>
的“非常好但不是很理想”的解决方案:
std
和shared_ptr
。weak_ptr
,与boost::local_shared_ptr兼容。[weak_ptr
可能是最好的即用型解决方案,它的质量很高,缺点也很少。
但是,要真正挤出最后几个字节并禁止复制,需要定制解决方案。
另外,从哲学上:
[从这里的讨论和其他阅读中,我都感觉到,很多人都相信所有权的二进制方法:要么是共享的(所以使用local_shared_ptr
,它也可以通过shared_ptr
为您提供共享的观察),或者是唯一的(因此使用weak_ptr
)。
这可能涵盖了90%以上的案例。但是我想要拥有共同观察力的唯一所有权(这是我的措辞;根据您的语义,您可以使用不同的词)。对于该资源受限的系统,该标准可能无法满足要求,但我认为这似乎是一个合理的市场。