Новое в классах и объектах в C ++ - PullRequest
0 голосов
/ 31 августа 2018

Я новичок в классах и объектах в C ++. Я не могу понять, почему связанный список не создается. Он просто запрашивает первое значение, а затем падает. Я не могу понять, где проблема и уже потратил слишком много часов на это. Наконец решил получить помощь. Спасибо за ваше время.

 #include <iostream>
 using namespace std;

 class Node{
 private:
     int data;
     Node* next;
     Node* previous;

 public:

     Node(int value){
        data = value;
        next = NULL;
        previous = NULL;
     }

     void setValue(int value)
     {
        data = value;
     }

     int getValue()
     {
         return data;
     }

     Node* getNext()
     {
         return next;
     }

     void setNext(Node* address)
     {
         next = address;
     }

     Node* getPrevious(){
        return previous;
     }

     void setPrevious(Node* address){
        previous = address;
     }

 };


class LinkedList{
private:
    Node* head;
    Node* tail;

public:

    LinkedList(){
        Node* head = NULL;
        Node* tail = NULL;
    }



    void createLinklist(){

        int n;
        cout << "Enter the number of nodes = ";
        cin >> n;



        for(int i=0;i<n;i++)
        {
            int value;
            cout << "Enter the value at " << i <<"=";
            cin >> value;

            Node* node = new Node(value);

            if(head == NULL)
            {
                head = node;
                tail = node;
            }
            else{
                insertAtEnd(node,tail);
            }

        }

    }


    void insertAtEnd(Node* newNode,Node* lastNode)
    {
        lastNode->setNext(newNode);
        newNode->setPrevious(lastNode);
        newNode->setNext(NULL);
        tail = newNode;


    }




    void display(){

    Node* start = head;

    while(start!=NULL)
    {
        cout << "Address=" << start << endl;
        cout << "value = " << start->getValue() << endl;
        cout << "Next = " <<  start->getNext() << endl;
        start = start->getNext();

    }

    }


};


 int main(){

    LinkedList newLink;
    newLink.createLinklist();
    newLink.display();

 }

Ответы [ 3 ]

0 голосов
/ 31 августа 2018

измените свой код на

    LinkedList(){
         head = NULL;
         tail = NULL;
    }

потому что вы уже определили head и tail.

0 голосов
/ 31 августа 2018

Проблема в вашем конструкторе:

class LinkedList{
private:
    Node* head;
    Node* tail;

public:

    LinkedList(){
        Node* head = NULL;
        Node* tail = NULL;
    }

В конструкторе вы объявляете две ЛОКАЛЬНЫЕ переменные в NULL, а не в класс. Это означает, что классовые указатели указывают куда угодно, но, по всей вероятности, не равны NULL.

Предложения: изучите C ++ 11 или более позднюю версию.

  • Использовать инициализацию членов класса.
  • Использовать nullptr вместо NULL
  • Избегайте использования новых и удаления. Научитесь использовать std :: unique_ptr по умолчанию, когда вы имеете дело с указателями, хотя я понимаю, что вы хотите научиться работать с указателями здесь, и std :: unique_ptrs на самом деле не является жизнеспособным решением для узлов связанных списков. на них не указывают однозначно. Так что забудьте этот совет для этого варианта использования, но все же, когда вы хотите что-то новое, всегда спрашивайте, не должен ли я вместо этого использовать std :: unique_ptr?

В основном C ++ 11 позволяет вам сделать это:

class LinkedList{
private:
    Node* head = nullptr;
    Node* tail = nullptr;

и вам не понадобится конструктор в вашем случае, хотя рекомендуется добавить:

LinkedList() = default;

, если вы хотите использовать по умолчанию.

0 голосов
/ 31 августа 2018

Задача

В

LinkedList(){
    Node* head = NULL;
    Node* tail = NULL;
}

Node* head = NULL; говорит компилятору создать новую переменную Automatic с именем head, которая является указателем на Node, и установить эту новую переменную на NULL. Это новый head shadows LinkedList::head, заменяющий его для остальной части конструктора. В результате head переменная, которая существует только в теле конструктора, получает инициализацию (действительно назначение) для LinkedList::head.

Это значит, что когда вы доберетесь до

if(head == NULL)

в createLinklist, LinkedList::head, вероятно, не NULL и вместо этого указывает на дикий синий цвет, поэтому программа выполняет

insertAtEnd(node,tail);

и LinkedList::tail постигла та же участь, что и LinkedList::head, и, вероятно, указывает куда-то, что вы не можете безопасно написать. Возможно, в этот момент программа завершает работу, но она может перезаписать что-то еще важное и вызвать сбой программы позже, скрывая истинное местоположение ошибки.

Решение

LinkedList(){
    head = NULL;
    tail = NULL;
}

назначает NULL to head and tail`. Более идиоматический подход заключается в использовании списка инициализирующих элементов

LinkedList(): head(NULL), tail(NULL)
{
    // does nothing.
}

Sidenote

хороший компилятор с включенным уровнем предупреждения предупредит вас, что

Node* head = NULL;

ничего полезного не делает. Никогда не игнорируйте предупреждения компилятора. Предупреждение компилятора означает, что, хотя ваша программа может быть синтаксически правильной, она, вероятно, не делает то, что вы хотите. Предупреждения - ваша первая линия защиты от логических ошибок. Всегда пытайтесь понять и понять, что говорит вам компилятор. Это может сэкономить вам часы отладки позже.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...