簡體   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