Ссылка, возвращающая пустое значение

#c #pointers #reference

Вопрос:

Я пишу связанный список и использую свою main функцию для его тестирования. Вот мой код:

 #include <iostream>
using namespace std;

class LinkedList {
  int value;
  LinkedList* next;

  public:

    LinkedList(int valueIn, LinkedList* nextIn) {
      value = valueIn;
      next = nextIn;
    }
    LinkedList(int valueIn) {
      value = valueIn;
    }

    int getValue() {
      return value;
    }

    void addNode(LinkedList* node) {
      next = node;
    }

    LinkedListamp; getNext() {
      return *next;
    }
};

int main() {
  cout << "starting..." << std::endl;
  LinkedList list1(1);
  LinkedList list2(2, amp;list1);
  cout << list1.getValue() << " --> " << list1.getNext().getValue() << std::endl;
  return 0;
}
 

Я ожидаю , что результат будет 1 --> 2 , но я получаю 1 --> . Насколько я понимаю, getNext() следует вернуть ссылку на другой список ( list2 в данном случае), но, похоже, что-то идет не так. Мои усилия по отладке показывают, что list2 при инициализации у него есть правильный value 2, но когда на него ссылаются для окончательного вывода, кажется, что у него ничего нет value . Я ни за что на свете не могу понять, почему это так. Может ли кто-нибудь помочь мне понять?

Комментарии:

1. Терминология: То, что вы называете связанным списком, обычно называется узлом или ссылкой. Класс связанного списка будет управлять списком связанных узлов.

2. Тактическое примечание: LinkedList(int valueIn) не следует оставлять next болтающимся. Вы должны по умолчанию завершить список, чтобы предотвратить возможные ошибки. Возможно, вы могли бы удалить эту функцию и заменить ее немного другой LinkedList(int valueIn, LinkedList* nextIn) -> > LinkedList(int valueIn, LinkedList* nextIn = nullptr) . Если вы не укажете значение для nextIn , компилятор вставит a nullptr , общий терминатор из связанных списков.

3. Спасибо за советы пользователю 4581301. Я думаю LinkedList , что как класс, представляющий как узел, так и целый список, работает, но, вероятно, было бы легче понять, если бы я создал LinkedList и node два отдельных класса. Я также не знал об этих опасных ошибках. Спасибо.

Ответ №1:

Вы вставляете list1(который на самом деле является узлом) в конец list2, а не наоборот, и все же вы вызываете getNext() list1 . Вы должны изменить код в основном на следующий:

 int main() {
  std::cout << "starting..." << std::endl;
  LinkedList list1(1);
  LinkedList list2(2, amp;list1);
  std::cout << list2.getValue() << " --> " << list2.getNext().getValue() << std::endl;
  return 0;
}
 

Пожалуйста, обратите внимание, что есть еще несколько вещей, которые было бы лучше изменить:

  1. Создайте класс списка и класс узла, чтобы сделать вещи более понятными
  2. Инициализация указателя NULL (или nullptr из C 11) в LinkedList(int valueIn) конструкторе
  3. Верните указатель на узел в getNext() , а не копируйте узел

Ответ №2:

Вы не получаете пустое значение. На самом деле ваша программа выходит из строя, когда вы пытаетесь вызвать list1.getNext().getValue() as getNext() , возвращая ссылку на НУЛЬ.

Вы делаете противоположное тому, что хотите сделать. Ваш list2 указывает list1 и list1 указывает на NULL .

Вы должны изменить свой код с помощью этого:

 LinkedList list2(2);
LinkedList list1(1, amp;list2);
cout << list1.getValue() << " --> " << list1.getNext().getValue() << std::endl;
 

Комментарии:

1. Спасибо-я думаю, это была довольно простая логическая ошибка. Я думал, что это как-то связано с непониманием указателей и ссылок с моей стороны, поскольку они являются для меня новой концепцией. Огромное спасибо за ответ.