C++ 使用智能指针实现简单的单链表

C++ 使用智能指针实现简单的单链表,c++,linked-list,shared-ptr,smart-pointers,unique-ptr,C++,Linked List,Shared Ptr,Smart Pointers,Unique Ptr,大家好,我正在尝试使用智能指针实现一个简单的单链接列表,这是我到目前为止所做的,我选择使用C++的共享\u ptr,但我了解到一个唯一的\u ptr更适合这种情况,但我真的不知道如何迭代列表(即currentNode=currentNode->next)到达列表末尾,以便使用唯一的\u ptr插入元素。以下是我目前掌握的代码: template <typename T> class LinkedList; template <typename T> class List

大家好,我正在尝试使用智能指针实现一个简单的单链接列表,这是我到目前为止所做的,我选择使用C++的共享\u ptr,但我了解到一个唯一的\u ptr更适合这种情况,但我真的不知道如何迭代列表(即currentNode=currentNode->next)到达列表末尾,以便使用唯一的\u ptr插入元素。以下是我目前掌握的代码:

template <typename T>
class LinkedList;

template <typename T>
class ListNode
{
public:
    ListNode() : _data(T()) {}
    explicit ListNode(const T& value) : _data(value) {}

    friend class LinkedList < T > ;
private:
    T _data;
    shared_ptr<ListNode<T>> _next;
};

template <typename T>
class LinkedList
{
public:
    void push_back(const T& value)
    {
        if (_root)
        {
            shared_ptr<ListNode<T>> currentNode(_root);

            while (currentNode->_next != nullptr)
            {
                currentNode = currentNode->_next;
            }

            currentNode->_next = make_shared<ListNode<T>>(value);
        }
        else
        {
            // If the list is completely empty,
            // construct a new root (first element)
            _root = make_shared<ListNode<T>>(value);
        }
    }

    void print() const
    {
        shared_ptr<ListNode<T>> currentNode(_root);

        while (currentNode != nullptr)
        {
            cout << currentNode->_data << " ";
            currentNode = currentNode->_next;
        }

        cout << endl;
    }
private:
    shared_ptr<ListNode<T>> _root;
};
模板
类链接列表;
模板
类ListNode
{
公众:
ListNode():_数据(T()){}
显式ListNode(常量T和值):\u数据(值){}
好友类链接列表;
私人:
T_数据;
共享\u ptr\u next;
};
模板
类链接列表
{
公众:
无效推回(常数T和值)
{
if(_根)
{
共享\u ptr currentNode(\u root);
while(currentNode->_next!=nullptr)
{
currentNode=currentNode->\u下一步;
}
currentNode->_next=使_共享(值);
}
其他的
{
//如果列表完全为空,
//构造新根(第一个元素)
_根=使_共享(值);
}
}
void print()常量
{
共享\u ptr currentNode(\u root);
while(currentNode!=nullptr)
{
下一步是收集数据;
}

cout使用
std::unique\u ptr
的循环可能如下所示:

// Iteration doesn't own resource, so no unique_ptr here.
ListNode<T>* currentNode(_root.get());

while (currentNode->_next != nullptr)
{
    currentNode = currentNode->_next.get();
}

currentNode->_next = make_unique<ListNode<T>>(value);
//迭代不拥有资源,因此这里没有唯一的\u ptr。
ListNode*currentNode(_root.get());
while(currentNode->_next!=nullptr)
{
currentNode=currentNode->_next.get();
}
currentNode->_next=使_唯一(值);

在这种情况下,你不能使用
unique\u ptr
。他们应该管理所有权,那么这些应该如何从其他地方链接?那么我在这种情况下使用shared\u ptr是否正确?你说我不能在这种情况下使用unique\u ptr,在什么情况下使用unique\u ptr合适?@userwhosename不能键入肯定可以。first节点将由LinkedList中的唯一\u ptr拥有。后续节点将由前一个节点中的唯一\u ptr拥有。@derektruong With
unique\u ptr
您有一个
unique\u ptr
指向对象,所有其他指针都是普通指针(
ListNode*
)这是一个有趣的问题,因为它确实概括了
shared\u ptr
vs
unique\u ptr
vs普通旧指针的用法。请注意,正如公认的答案所暗示的,对节点使用
unique\u ptr
shared\u ptr
与遍历结构的方式是正交的,因为解决方案使用普通指针。oth,它会影响您如何使用这些列表(使用
unique\u ptr
创建时复制,使用
shared\u ptr
共享内容)。为了澄清,如果我实例化LinkedList intLinkedList;当intLinkedList超出范围时,\ u根将被销毁,这将销毁\ u根正在管理的ListNode,这将导致一系列删除,因为销毁根将导致销毁\ u next,这将导致销毁下一个节点,等等,等等?是的,
\u root
的析构函数调用(隐式地感谢智能指针)对
\u next
的析构函数,该函数调用..,直到
\u next
为空并停止链接。
// Iteration doesn't own resource, so no unique_ptr here.
ListNode<T>* currentNode(_root.get());

while (currentNode->_next != nullptr)
{
    currentNode = currentNode->_next.get();
}

currentNode->_next = make_unique<ListNode<T>>(value);