如何在双向链表上实现复制分配?

How to implement a copy assignment on a doubly linked List?

提问人:Jay 提问时间:1/19/2020 最后编辑:Jay 更新时间:1/19/2020 访问量:747

问:

我对如何在双链接列表上实现复制分配有点困惑。我设法让复制构造函数工作,但我不确定分配。我试图在没有复制和交换方法的情况下做到这一点。

列表.H

class List 
{
public:
    List();
    ~List();
    List(const List& c);
    List& operator= (const List& t);
private:
    List *Next;
    List *Prev;
    Node *Head;

List.cpp

List::~List()
{
    Node* move = Head;
    while (move!=NULL)
    {
        Node *temp = move->Next;
        delete move;
        move = temp;
    }
}

List::List(const List& c)
{
    name = c.name;
    Prev = c.Prev;
    Next = c.Next;
    Node* dummy, * current;
    Head= dummy = new Node();
    current = c.Head;
    while (current)
    {
        dummy->Next = new Node(*current);
        current = current->Next;
        dummy = dummy->Next;
    }

    Node* temp = Head;
    Head = Head->Next;
    delete temp;
}

List& List::operator=(const List& t)
{
    Next = t.Next;
    return *this;
}

我是否还必须遍历赋值运算符中的每个节点?

编辑 这就是我现在所拥有的。问题是当我从列表中获取数据时,它是空的。

List& List::operator=(const List& that)
{

    if (this != &that)
    {
        while (Head)
        {
            Node* temp = Head;
                Head = Head->Next;
                delete temp;
        }
        Node* dummy, * current;
        Head = dummy = new Node();
        current = that.Head;
        while (current)
        {
            dummy->Next = new Node(*current);
            current = current->Next;
            dummy = dummy->Next;
        }
    dummy->Next = nullptr;
}
return *this;
}

C++ 构造函数 doublebly-linked-list assignment-operator

评论

1赞 Raymond Chen 1/19/2020
复制和交换有什么问题?它还有一个额外的好处,即是异常安全的(假设你的副本是例外安全的)。
0赞 TruthSeeker 1/19/2020
copy-ctor而且两者都在做浅拷贝。由于来自两个不同对象的相同内存,这可能会导致未定义的行为operator=delete
0赞 Lukas-T 1/19/2020
@TruthSeeker copy-ctor 对列表进行深度复制。只有,无论它们是什么,都不会被深度复制,但它们也不会在析构函数中删除,所以应该没问题。PrevNext
0赞 TruthSeeker 1/19/2020
@churill:是的,你是对的,即使它被分配了它没有被删除。但不确定 和 的意义。@Jay任何解释和用例?NextPreviousNextPrevious

答:

1赞 TruthSeeker 1/19/2020 #1

简短的回答是肯定的。

  1. copy-构造函数
    List L1;
    List L2(L1);
  1. 运算符=
    List L1;
    List L2;
    L2 = L1;

在这两种情况下,都必须复制到,并且在复制或分配后应保持不变。因此,必须将每个节点的内容复制到新创建的节点。L1L2L1

复制构造函数如下所示:

List::List(const List& c)
{
    Node start;
    Node* dummy = &start;
    Node* CurrentNode = c.Head;
    while (CurrentNode)
    {
        dummy->next  = new Node(*CurrentNode);//New node created with content of *CurrentNode
        dummy = dummy->Next;
        CurrentNode  = CurrentNode->Next;
    }

    dummy->next = nullptr;
    Head = start.next;
}

赋值运算符如下:

List& List::operator=(const List& that)
{
    if (this != &that) //avoid self assignment like List L1;L1=L1;
    {
       while (Head)//Delete exist nodes
       {
           Node* temp = Head;
           Head = Head->Next
           delete temp;
       }

        Node start;
        Node* dummy = &start;
        Node* thatHead = that.Head;
        while (thatHead)
        {
            dummy->next  = new Node(*thatHead);//New node created with content of *thatHead 
            dummy = dummy->Next;
            thatHead = thatHead->Next;
        }
        dummy->next = nullptr;
    }
    return *this;
}

评论

0赞 Jay 1/19/2020
当执行 while(that) 时,我得到一个 exprssion must have bool type 错误,并且在创建一个内容为 *的新节点时,我得到“没有运算符与这些操作数匹配。While 循环不需要是 while (&that)。
0赞 TruthSeeker 1/19/2020
@Jay:我已经更新到了片段。这里是,我们需要遍历列表节点thatList