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

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

本文关键字:链表 复制 构造函数 智能 何利用 指针 实现 单链表      更新时间:2023-10-16

这是我第一次在这里发布问题!我在为单链表创建复制构造函数时遇到了一些麻烦。我在这个和其他各种网站上搜索了一个类似的例子,但无济于事。我试着使用智能指针,到目前为止,我只使用了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);
    }
}

UPDATE # 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);
       } 
    }
}

您没有发布多少关于您的DequeNode类实际上看起来确切的信息。根据您的代码片段浏览的信息,您的主要问题是您使用std::unique_ptr<T>来导航您的列表:这将不起作用:每当分配或销毁非空std::unique_ptr<T>时,它将释放持有的对象。你需要一个非归属的指针。

因为你没有发布太多的上下文信息,我不能很容易地测试这段代码是否有效,但我认为它应该是好的:

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来维护初始节点的目的。