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

问题描述 投票:0回答:2

以下是我对智能指针的了解

  1. shared_ptr是一个智能指针,这样多个shared_ptr可以指向堆中的对象。即使删除了其中一个shared_ptr,只要它的引用计数大于零,堆中的对象就不会被销毁。
  2. weak_ptr也指向堆中的对象,但它不会增加该对象的引用计数
  3. 我们可以使用weak_ptr来打破循环引用

在双链接列表的情况下,我们有两个指针指向前一个节点和下一个节点。我们在实现中使用shared_ptr和weak_ptr。为什么我们不使用两个weak_ptr?

c++ pointers c++14 smart-pointers weak-ptr
2个回答
3
投票

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

想象一下有两个节点的列表。列表头是第一个节点的非弱ptr。所以第一个节点保持活跃状态​​。但是什么非弱指针使第二个节点保持活着?

管理对象的生命周期有两个挑战。他们应该活得足够长,但不能太久。这不仅适用于C ++或智能指针,这是几乎所有编程语言中的基本问题。您可以通过了解您正在处理的问题并在您的语言为您提供的工具中表达该问题来解决问题。


1
投票

我们可以使用shared_ptrnextweak_ptrprev,但不是两个weak_ptr。如果没有指向节点的shared_ptr,则引用计数变为零,并且weak_ptr变为nullptr

无论如何,使用shared_ptr作为链接列表是一种矫枉过正。由于只有一个对象拥有节点(头部或前一个节点),因此unique_ptr的简单next将使用指向prev的原始指针。

请注意,使用智能指针对链表很有风险。当一个长列表被破坏时,问题出现了,它正在被递归破坏。 Node析构函数调用智能指针的析构函数,该析构函数调用节点析构函数。很可能stacj将在O(n)中增长。由于列表可能比最大可能堆栈长,因此代码可能会耗尽堆栈空间并崩溃。

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

© www.soinside.com 2019 - 2024. All rights reserved.