如何使用智能指针为单链表实现复制构造函数

How to implement a copy constructor for a singly linked list utilizing smart pointers

这是我第一次真正在这里发布问题!我在为单链表创建复制构造函数时遇到了一些问题。我在这个网站和其他各种网站上到处搜索了一个可比较的例子,但无济于事。我试图使用智能指针,但到目前为止只使用了 unique_ptr(s)。此函数旨在对正在传递的链表进行深度复制。到目前为止,我已经尝试了以下操作,但我只遇到了段错误。我已经 运行 进行了一些测试,我相信我的 insert_front()insert_back() 功能运行良好。如果有帮助的话,我确实有指向头部和尾部的指针。以下是我试过的代码。

Deque::Deque(const Deque& deque2copy){
    this -> head = 0;
    unique_ptr<Node> temp = make_unique<Node>(deque2copy.head -> val, move(deque2copy.head->next));
    while(temp != 0){
        this ->insert_back(temp->val);
        temp = move(temp-> next);
    }
}

更新#1

Deque::Deque(const Deque& deque2copy){

    if(deque2copy.head->next == nullptr){
        return;
    } else {
       this -> head = 0;
       unique_ptr<Node> temp = make_unique<Node>(*deque2copy.head->next);
       while(temp != 0){
            this ->insert_back(temp->val);
            temp = move(temp-> next);
       } 
    }

}

您没有 post 太多关于您的 DequeNode 类 实际长什么样的信息。根据从您的代码片段中看到的信息,您的主要问题是您使用 std::unique_ptr<T> 来导航您的列表:那是行不通的:每当分配或销毁非空 std::unique_ptr<T> 时,它都会释放持有的对象。您将需要一个非拥有指针。

由于您没有 post 太多上下文信息,我无法轻松测试此代码是否有效,但我认为它应该没问题:

Deque::Deque(const Deque& deque2copy)
    : head() { // the default constructor does the null-initialization
    std::unique_ptr<Node>* tail(&this->head);
    for (Node* temp(deque2copy.head.get()); temp; temp = temp->next.get()) {
        *tail = std::make_unique<Node>(temp->value);
        tail = &tail->next;
    }
}

请注意,此代码使用非拥有指针导航两个列表:

  • 对于源列表,它使用从 std::unique_ptr<Node>::get() 获得的 Node* 来避免在分配或销毁 std::unique_ptr<Node> 时销毁 Node 对象。
  • 对于目标列表,指向列表中当前最后一个 std::unique_ptr<Node> 的指针 tail(最初是 head,一旦它被分配到列表中的最后一个 next 指针列表)被保留以有效地附加一个节点。

代码确实假设 Node 有一个构造函数将 value 作为构造函数参数。此构造函数将相应地初始化 value 成员并默认初始化 next 成员,例如:

Node::Node(T const& value)
    : value(value)
    , next() {
}

请注意,对列表元素使用拥有指针通常不是一个好主意:head 的析构函数将递归调用列表中所有节点的析构函数。根据实际编写析构函数的方式,此递归可能很容易造成堆栈溢出。为了解决这个问题,您需要为您的列表编写自定义析构函数以避免这种递归。但是,这样做完全违背了使用 std::unique_ptrs 来维护开始的节点的目的。