8

我之所以这么问,是因为出于许多明显的原因,这是一个令人衰弱的限制,但我确信 C++ 标准人员有充分的理由这样做,我想知道它是什么。不是因为它会有所作为,而是因为它会让我感觉更好,因为它知道有一个很好的理由。

这是我目前的看法;正如我所见,弱指针有两个主要用途:

1) 避免所有权循环。2) 减少与围绕大量共享指针弹跳相关的开销。

通过实现weak_ptr.get(),前者的服务不会少,后者的服务更好,那为什么不存在呢?更重要的是,weak_ptr.get() 不会比weak_ptr.lock().get() 更有效,还是编译器可以优化它以使其相同?

4

3 回答 3

10

弱指针需要能够检查它引用的智能指针是否仍然有效。如果它不能做到这一点,那么您在get实际使用它时就无法知道结果是否有效。

这就是为什么有lock; 它为您提供了一个智能指针,只要您需要它就有效(预计不会很长)。

如果您想要直接访问,那么您真正想要的是一个普通的“哑”指针。

于 2013-06-23T23:47:03.740 回答
1

1) 避免所有权循环。2) 减少与围绕大量共享指针弹跳相关的开销

通过实现weak_ptr.get(),前者的服务不会少,后者的服务更好,那为什么不存在呢?更重要的是,weak_ptr.get() 不会比weak_ptr.lock().get() 更有效,还是编译器可以优化它以使其相同?

前者是正确的,后者是错误的——弱指针并不是神奇的低成本共享指针……它们在功能上是不同的。你需要选择一个适合你的情况。

使用弱指针的主要原因是跟踪一些您可能想要使用的数据,如果它仍然存在,但可以在没有它的情况下愉快地生存。建立这涉及与共享指针的用户的竞争条件,因此除非您对对象的生命周期有一些内部了解,这意味着您可以确定您的代码可以在对象被销毁之前完成,否则原始指针将毫无用处。如果您确实有内部洞察力,那么您最初可以得到一个原始指针 -而不是弱指针 - 但是弱指针的设计旨在阻止您意外获得一个并创建不安全的代码。事实上,面对代码的中/长期演变,任何这样的洞察力都可能是脆弱的,所以除非绝对必要,否则最好不要尝试进行这样的优化。

也许一个很好地使用弱指针的例子会有所帮助......

假设一个对象代表屏幕上的某些东西——如果你想让它闪烁,你可以将一个弱指针添加到一个计时器驱动的闪光灯列表中,然后你就可以忘记它了。当计时器下一次触发时,如果 Flasher 代码发现该对象事先被销毁(即它不再出现在屏幕上),则 flasher 只会将其从列表中删除,但它不想共享所有权并不自然地保留该对象。这可能比当对象从屏幕上消失而不得不将其从闪光灯列表中删除(并可能阻止等待锁定这样做)时尝试让代码跟踪更容易。

于 2013-06-24T01:22:09.410 回答
0

这是因为 shared_ptr/weak_ptr 对的设计者认为最好让我们免于自己的伤害,并确保当我们知道这无关紧要时,我们不能以牺牲优化为代价错误地使用它。可能没有必要让线程安全和所有权语义相同 - 很容易提出一个单线程代码块,其中有一个很好的智能指针知道它的 null 是有益的,但锁定的开销是,虽然没有使人衰弱,但绝对是一种悲观情绪。

shared_ptr/weak_ptr 是否应该允许这样做(在目标销毁时添加 notad_ptr where notad - null ,但不一定是线程安全的),或者这应该是一种新型的 shared_ptr 是有争议的。

我们在代码库中通过添加一种支持这些语义的新型智能指针来解决这个问题。然而,这绝对不是最优的,因为拥有不符合标准的智能指针肯定很烦人,但额外的有用语义不仅弥补了我们可能不像完整的标准化委员会那样聪明 [双关语!] 的事实:- )

于 2013-06-24T08:47:17.127 回答