繁体   English   中英

双链表C ++的赋值运算符

[英]Assignment Operator for Doubly Linked List C++

我一直无法让我的赋值运算符使双向链接列表正常工作。 当rhs是一个空列表时,该操作符可以正常工作,但是如果填充了该操作符,则该操作符将不起作用,并抛出异常错误,指出“读取访问冲突”

这是我的主程序,将不会运行。

#include <cstdlib>

#include "linkedlist.h"

using namespace std;

int main()
{
    LinkedList e1;
    e1.insertToFront("A");
    e1.insertToFront("B");
    e1.insertToFront("C");

    LinkedList e2;

    e2.insertToFront("Please work");

    e1 = e2; //Expecting e1 to now just hold "Please work".

    system("pause");
}

这是赋值运算符本身(在单独的头文件中)。

// assignment operator
const LinkedList& LinkedList::operator=(const LinkedList& rhs)
{
    Node* temp;
    temp = head;
    Node* forward;
    forward = new Node;

    while (temp != nullptr) // clear memory of target variable
    {
        forward = temp->next;
        delete temp;
        temp = forward;
    }

    if (rhs.head == nullptr)
    {
    head = nullptr;
    tail = nullptr;
    } 
      //GOOD THROUGH THIS PNT.

    else
    {       
        temp = rhs.head;

        while (temp != nullptr)
        {
            this->addToEnd(temp->value);
            temp = temp->next;
        }
    }

    return *this;
}

这是我调用的addToEnd函数以及Node结构。

void LinkedList::addToEnd(const ItemType& val) 
{
    Node* temp;
    temp = new Node;
    temp->value = val;

    if (this->head == nullptr)
    {
        head = temp; // make new node head if list is empty
        head->next = nullptr;
        head->prev = nullptr;
        tail = temp;
    }

    else
    {
        temp->prev = tail; // otherwise point current tail towards temp
        temp->next = nullptr;
        tail->next = temp;
        tail = temp;
    }

    return;
}

////////////////////////////////////////////////////////////////////////

struct Node
{
    ItemType value;
    Node* next;
    Node* prev;
};

您删除了旧节点,但是忽略了将headtail设置为nullptr ,因此这些指针仍然指向已删除的对象。 然后,您尝试将元素添加到该已删除列表中,并获得未定义行为。

当清除现有节点时,在开始从源列表中复制值之前,无需将headtail指针重置为nullptr 因此,您正在使用无效的指针将新的Node添加到列表中。

您还存在少量内存泄漏,因为您正在为forward变量分配新的Node ,然后如果源列表不为空,则立即重新分配forward以指向另一个Node 您永远不会使用new delete分配的Node 清除现有节点时,您不应分配任何资源。

为了使事情更安全一些,您应该将列表的清除内容包装在其自己的单独方法中,然后可以在需要时调用该方法(不要忘了在析构函数中,而不仅仅是在operator= )。

如果您使用copy-and-swap习语按照复制构造函数(确实有一个,对吗?)实现赋值operator=会更好。 并且由于您显然使用的是C ++ 11或更高版本,因此还应该实现move构造函数。 这些步骤将大大简化您的operator=实施并使其更安全。

尝试这个:

class LinkedList
{
public:
    LinkedList() = default;
    LinkedList(const LinkedList& src);
    LinkedList(LinkedList&& src);
    ~LinkedList();
    ...
    LinkedList& operator=(LinkedList rhs);
    ...
private:
    Node *head = nullptr;
    Node *tail = nullptr;
    ...
};

#include <utility>

LinkedList::LinkedList(const LinkedList& src)
{
    Node* temp = src.head;
    while (temp)
    {
        addToEnd(temp->value);
        temp = temp->next;
    }
}

LinkedList::LinkedList(LinkedList&& src)
    : head(src.head), tail(src.tail)
{
    src.head = src.tail = nullptr;
}

LinkedList::~LinkedList()
{
    clear();
}

void LinkedList::clear()
{
    Node *temp = head;
    head = tail = nullptr;
    while (temp)
    {
        Node *forward = temp->next;
        delete temp;
        temp = forward;
    }
}

LinkedList& LinkedList::operator=(LinkedList rhs)
{
    std::swap(head, rhs.head);
    std::swap(tail, rhs.tail);
    return *this;
}

您还可以insertToFront()简化insertToFront()addToEnd()方法:

struct Node
{
    ItemType value;
    Node* next = nullptr;
    Node* prev = nullptr;

    Node(const ItemType& val) : value(val) {}
};

void LinkedList::insertToFront(const ItemType& val) 
{
    Node* temp = new Node(val);

    if (!tail)
        tail = temp; // make new node tail if list is empty

    if (head)
    {
        temp->next = head; // point current head towards temp
        head->prev = temp;
    }

    head = temp;
}

void LinkedList::addToEnd(const ItemType& val) 
{
    Node* temp = new Node(val);

    if (!head)
        head = temp; // make new node head if list is empty

    if (tail)
    {
        temp->prev = tail; // point current tail towards temp
        tail->next = temp;
    }

    tail = temp;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM