Оператор назначения не работает должным образом в круговом двусвязном списке - PullRequest
1 голос
/ 14 марта 2020

Я делаю двусвязный список с сторожевым узлом, который делает двусвязный список круглым списком (нет заголовка и хвостовых указателей спереди и сзади, вместо заголовка упоминается m_sentinel-> m_next и хвост называется m_sentinel-> m_prev). Вот следующий код:

В MyList.h:

template <typename T>
class Node
{
    public:
        T m_element;

        Node<T> *m_prev;
        Node<T> *m_next;

        // Helps make a dummy/sentinel/junk node
        Node(Node<T> *in_prev, Node<T> *in_next): 
            m_prev(in_prev), m_next(in_next){}

        Node(const T &x, Node<T> *in_prev, Node<T> *in_next): 
            m_element(x), m_prev(in_prev), m_next(in_next){}
};

template <typename T>
class MyList
{
    private:
        Node<T> *m_sentinel = nullptr;

        int m_size;

    public:
        MyList();

        ~MyList();

        MyList<T> & operator=(const MyList<T> &source);

        void clear();

        void push_back(const T &x);

В MyList.hpp:

template <typename T>
MyList<T>::MyList()
{
  m_size = 0;
  m_sentinel = new Node<T>(NULL, NULL);
}

template <typename T>
MyList<T>::~MyList()
{
  clear();

  m_size = 0;
}

template <typename T>
MyList<T> & MyList<T>::operator=(const MyList<T> &source)
{
  if(this == &source)
  {
    return *this;
  }
  while(source.m_sentinel->m_next != source.m_sentinel)
  {
    Node<T> *temp = source.m_sentinel->m_next;
    push_back(temp->m_element);
    source.m_sentinel->m_next = temp->m_next;
  }

  return *this;
}

template <typename T>
void MyList<T>::clear()
{
  if(m_sentinel->m_prev == NULL && m_sentinel->m_next == NULL)
  {
    delete m_sentinel;
  }
  else
  {
    int k = size();
    for(int i = 0; i < k; i++)
    {
      pop_back();
    }
    delete m_sentinel;
  }
}

template <typename T>
void MyList<T>::push_back(const T &x)
{
  Node<T> *newNode;
  newNode = new Node<T>(x, NULL, NULL);
  if(m_sentinel->m_prev == NULL && m_sentinel->m_next == NULL)
  {
    newNode->m_prev = m_sentinel;
    newNode->m_next = m_sentinel;
    m_sentinel->m_prev = newNode;
    m_sentinel->m_next = newNode;
  }
  else
  {
    newNode->m_next = m_sentinel;
    newNode->m_prev = m_sentinel->m_prev;
    Node<T> *temp = newNode->m_prev;
    m_sentinel->m_prev = newNode;
    temp->m_next = m_sentinel->m_prev;
  }
  m_size++;
}

В основном. cpp:

#include "MyList.h"

int main()
{
    MyList<int> x;
    x.push_front(1);
    x.push_front(2);
    x.push_front(3);
    x.push_front(4);
    x.push_front(5);
    x.push_front(6);
    x.push_front(7);
    MyList<int> p;
    p = x; 

    // Below just outputs each linked list
    int j = 0;
    int m = x.size();
    cout << endl << endl;
    for(auto i = 0; i < m; i++)
    {
        cout << x.front() << endl;
        x.pop_front();
        j++;
    }
    cout << endl << endl;
    j = 0;
    m = p.size();
    for(auto i = 0; i < m; i++)
    {
        cout << p.front() << endl;
        p.pop_front();
        j++;
    }
    cout << endl << endl;

При запуске этого кода x успешно копируется в p. При выводе p выдается следующий вывод: 7 6 5 4 3 2 1, но при выводе x выдается следующий вывод: -19823746 ... это просто значения ненужной памяти (что говорит о том, что x явно изменяется, но р успешно получает содержимое х). Я понятия не имею, почему это меняется; Я ищу исправление / решение для оператора присваивания, потому что оно не работает должным образом.

1 Ответ

1 голос
/ 15 марта 2020

Внутри вашего MyList::operator= вы должны перебирать новую переменную, а не сам элемент source.m_sentinel. Это изменяет фактический список и фактически удаляет узлы.

Используйте это вместо:

Node<T>* current = source.m_sentinel;
while (current->m_next != source.m_sentinel) {
  Node<T>* temp = current->m_next;
  push_back(temp->m_element);
  current = temp;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...