在双向链接列表中使用智能指针

时间:2018-09-02 23:38:27

标签: c++ pointers c++14 smart-pointers weak-ptr

这是我对智能指针的了解

  1. shared_ptr是一个智能指针,因此多个shared_ptr可以指向堆中的一个对象。即使shared_ptr之一被删除,只要引用计数大于零,堆中的对象也不会被破坏。
  2. weak_ptr也指向堆中的一个对象,但不会增加该对象的引用计数
  3. 我们可以使用weak_ptr打破循环引用

对于双链表,我们有两个指针指向上一个和下一个节点。我们在实现中使用了shared_ptr和weak_ptr。为什么不使用两个weak_ptr?

2 个答案:

答案 0 :(得分:3)

我们不使用两个weak_ptr,因为它不起作用。

想象一个有两个节点的列表。列表头是第一个节点的非弱ptr。因此,第一个节点保持活动状态。但是什么非弱指针可以使第二个节点保持活动状态?

管理对象的生存期面临两个挑战。它们应该存活足够长的时间,但不能太长。这不仅适用于C ++或智能指针,这实际上是所有编程语言中的基本问题。通过了解您正在解决的问题,并使用您的语言为您提供的工具来表达该问题,您可以解决该问题。

答案 1 :(得分:1)

我们可以使用shared_ptrnextweak_ptrprev,但不能使用两个weak_ptr。如果没有shared_ptr指向一个节点,则引用计数将变为零,而weak_ptr将变为nullptr

无论如何,对链接列表使用shared_ptr实在是太过分了。由于节点(头或上一个节点)仅拥有一个对象,因此unique_ptr只需一个简单的next,并带有指向prev的原始指针

请注意,使用智能指针存在链表风险。当长列表被销毁时,就会出现问题,而递归销毁它。节点析构函数调用智能指针的析构函数,后者调用节点析构函数。 stacj最有可能在O(n)中增长。由于列表的长度可能超过最大可能的堆栈,因此代码可能耗尽堆栈空间并崩溃

这并不意味着不能使用智能指针,只是节点必须实现析构函数。析构函数必须在循环中擦除节点,以便不会调用递归。