我问这个是因为这是一个令人虚弱的限制因为一些显而易见的原因但我确信C ++标准人员有充分的理由这样做,而且我想知道它是什么。并不是因为它会产生任何影响,而是因为它会让我感觉更好,因为它有充分的理由。
这是我目前对此的看法;我认为弱指针有两个主要用途:
1)避免所有权循环。 2)减少与大量共享指针相关的开销。
前者不会更少服务,而后者通过实施weak_ptr.get()更好地服务,那么它为什么不存在呢?更重要的是,weak_ptr.get()不会比weak_ptr.lock()。get()更有效,或者编译器可以优化它是否相同?
答案 0 :(得分:10)
弱指针需要能够检查它引用的智能指针是否仍然有效。如果它无法做到这一点,那么在您实际使用它时,您无法知道get
的结果是否有效。
这就是为什么lock
;它为您提供了一个智能指针,只要您需要它就会有效(预计不会很长)。
如果你想直接访问,那么你真正想要的是一个普通的“哑”指针。
答案 1 :(得分:1)
1)避免所有权循环。 2)减少与大量共享指针相关的开销
前者的服务不会少,而后者通过实施weak_ptr.get()可以更好地服务,那么为什么它不存在呢?更重要的是,不会使weak_ptr.get()比weak_ptr.lock()。get()更有效,或者编译器可以将它优化为相同吗?
前者是真的,后者是错的 - 弱指针不是神奇的低成本共享指针......它们在功能上是不同的。你需要选择一个适合你情况的。
使用弱指针的主要原因是跟踪一些你可能想要使用的数据,如果它仍然闲置,但可以幸福地生存。建立涉及共享指针用户的竞争条件,因此除非您对对象的生命周期有一些内部洞察,这意味着您可以确定您的代码可以在对象被销毁之前完成,原始指针将是无用。如果你确实有内部洞察力,那么你最初可以得到一个原始指针 - 而不是弱指针 - 但弱指针的设计旨在阻止你不小心得到一个并创建不安全的代码。实际上,面对代码的中长期演变,任何这样的洞察力都可能是脆弱的,所以除非绝对必要,否则最好不要尝试进行这样的优化。
也许好好利用弱指针的例子会有所帮助......
假设某个对象在屏幕上显示某些内容 - 如果您希望它闪烁,则向指向定时器的闪光灯列表添加一个弱指针,然后您可以忘记它。当计时器下一次触发时,如果Flasher代码发现该对象事先被破坏(即它不再在屏幕上),则闪存器会从列表中删除它,但它并不想共享所有权并保持不自然的物体。这可能比当对象从屏幕上从闪存列表中撕掉(并且可能阻止等待锁定等)时尝试进行代码跟踪更容易。
答案 2 :(得分:0)
这是因为shared_ptr / weak_ptr对的设计者决定最好将我们从自己身上拯救出来并确保我们不能错误地使用它错误地以牺牲优化为代价当我们知道它没有没关系可能没有必要让线程安全和所有权语义成为同一个东西 - 很容易想出一个单线程代码块,其中有一个很好的智能指针,知道它的null是有益的,但锁定的开销是,虽然不是使人衰弱,但绝对是一种悲观。
shared_ptr / weak_ptr是否应该允许这个(添加说notad_ptr,其中notad - null对目标销毁,但不一定是线程安全),或者这应该是一种新类型的shared_ptr是值得商榷的。
我们在代码库中通过添加一种支持这些语义的新型智能指针来解决这个问题。然而,这绝对不是最佳的,因为具有非标准兼容的智能指针肯定是令人讨厌的,但是额外的有用语义不仅仅弥补了我们可能不像完整的标准化委员会那样聪明[双关语意图!]的事实: - )