将weak_ptr应用于unique_ptr的内容

4
我正在尝试理解c++11中引入的unique_ptrshared_ptrweak_ptr
听说weak_ptr对于缓存、打破循环等方面非常有用。我听说它们与shared_ptrs很配合使用。
但在这方面,shared_ptrsunique_ptrs之间有什么区别呢?为什么weak_ptr只能与其中一个一起使用?为什么我不想拥有指向其他所有者拥有的对象的弱引用呢?
3个回答

7
一个weak_ptr实际上是一种保留一组管理某个共享对象的shared_ptr的引用计数的方式。当最后一个shared_ptr被销毁时,该对象也会被销毁,但只要还有weak_ptr指向它,其引用计数就会继续存在。因此,通过任何仍然存在的weak_ptr,您都可以检查对象是否仍然存在或已被销毁。
如果它仍然存在,则可以从weak_ptr获取一个shared_ptr,让您引用该对象。
主要用途是打破循环依赖。
特别地,一个对象可以包含一个持有其自身引用计数的weak_ptr,这样您就可以从对象本身获取到一个shared_ptr来引用该对象。也就是说,一个使用与其他指向该对象的shared_ptr相同的引用计数的shared_ptr。这就是enable_shared_from_this的工作原理。 unique_ptr没有任何引用计数,因此保留该不存在的引用计数就没有意义。

8
这的主要用途是打破循环依赖”我不同意这个说法。weak_ptr 的主要用途是访问你不需要拥有但可能在你没有观察时被删除的对象。有一种看法认为,对象可能仍然存在或不存在,需要进行检查。 - Nicol Bolas
谢谢,我之前并不真正理解弱指针的作用,现在更加清晰了。 - Matt Phillips

4
弱指针的主要优势是可以尝试将其转换为强指针,也就是拥有所有权:
auto strongPtr = weakPtr.lock();

if (strongPtr)
{
    // still existed, now have another reference to the resource
}
else
{
    // didn't still exist
}

请注意第一个路径:使弱指针变得更强需要我们拥有该对象的所有权
这就是为什么使用unique_ptr没有意义的原因:使弱指针变强的唯一方法是从其他地方获取资源,而对于unique_ptr来说,这意味着留下一个意外的空指针。 shared_ptr之所以能够通过是因为它的获取实际上是共享的。

2
@Verdagon:我们已经有了一种非拥有型指针。它叫做指针。我们不需要为此特别的类型或语法;它已经内置于语言中。智能指针都是关于所有权关系的。所以,如果你不想让某人拥有指针,就传递一个指针即可。 - Nicol Bolas
1
哦!我以为新类型的指针几乎会完全取代常规指针。看到它们适合于新方案真是有趣! - Verdagon
1
@Verdagon:就我所知,我能想到的最接近的概念是一种“被监视”的指针,它是一个具有单个唯一所有者(类似于unique_ptr)但也具有“被监视”的引用(类似于weak_ptr),可以告诉我们是否仍然拥有唯一拥有的资源。但是如果没有实际获取该资源的方法,我看不出有什么用处。 - GManNickG
1
@Verdagon:这样做是可行的,但我不会创建它或推荐它,因为很容易犯错误。想象一下,你调用get(),得到一个非空指针,但由于某些副作用,在下一行中原始的unique_ptr释放了其资源。现在你的指针是无效的。听起来可能很容易避免,但需要非常小心的操作!你必须确保每个操作直接在get()上操作,而不是存储它,但这是不可能强制执行的,也不安全。使用shared_ptr/weak_ptr要简单得多。 - GManNickG
@Verdagon,没有人提出要废除指针,我不知道你从哪里得到这个想法。虽然有一个世界上最愚蠢的智能指针的提案 - Jonathan Wakely
显示剩余2条评论

2

我也是C++11的新手,如果有更好的方法,请指正。

我认为如果没有特殊原因,使用shared_ptr会使unique_ptr失去其目的。 unique_ptr具有隐含的语义,即对其指向的对象拥有完全控制权。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接