Неопределенная ссылка на 'Inventory :: insertEnd (Node *, int)' - PullRequest
1 голос
/ 27 февраля 2020

При попытке собрать / скомпилировать мою программу появляется ошибка «неопределенная ссылка»:

obj \ Debug \ main.o || В функции main':| C:\Users\user1\Desktop\Project5Example\main.cpp|13|undefined reference to Inventory :: insertEnd (Узел *, int) '| ... || ошибка: ld вернул 1 статус выхода | || === Сбой сборки: 4 ошибки, 0 предупреждений (0 минут, 1 секунд) === |

Я новичок на с ++. Что я делаю неправильно? и как я могу это исправить? Я чувствую, это связано с моим головным узлом? Но не могу понять, как это.

Ошибка происходит на главной. cpp строка head = inventory1.insertEnd(head, 8);

Вот мой код:

Inventory.h

#ifndef INVENTORY_H
#define INVENTORY_H

#include <cstdlib>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <string>


using namespace std;

        struct Node
        {
            int data;
            Node* next;
        };

class Inventory
{
    public:
        // Default Constructor
        Inventory();

        // MODIFICATION MEMBER FUNCTIONS
        Node *newNode(int data);
        Node* insertEnd(Node* head, int data);

    private:
        // Data members
        Node *head;
        Node *trailer;
};

#endif // INVENTORY_H

Inventory. cpp

#include "Inventory.h"
#include <cstdlib>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <string>
#include <bits/stdc++.h>

using namespace std;

Inventory::Inventory()
{
    // Set the header and trailer to NULL
    head = NULL;
    trailer = NULL;
}

// Allocates a new node with given data
Node *newNode(int data)
{
    Node *new_node = new Node;
    new_node->data = data;
    new_node->next = NULL;
    return new_node;
}

// Function to insert a new node at the
// end of linked list using recursion.
Node* insertEnd(Node* head, int data)
{
    // If linked list is empty, create a
    // new node (Assuming newNode() allocates
    // a new node with given data)
    if (head == NULL)
        return newNode(data);

    // If we have not reached end, keep traversing
    // recursively.
    else
        head->next = insertEnd(head->next, data);
    return head;
}

main. cpp

#include <iostream>
#include "Inventory.h"

using namespace std;

int main()
{
    // Create an inventory list
    Inventory inventory1;

    Node* head = NULL;

    head = inventory1.insertEnd(head, 8);
    head = inventory1.insertEnd(head, 11);
    head = inventory1.insertEnd(head, 20);

    return 0;
}

1 Ответ

1 голос
/ 27 февраля 2020

Для начала структура Node должна быть частным членом класса Inventory. Соответственно, класс Inventory не должен содержать публичные c функции-члены, которые имеют тип возврата Node *. Так, например, эту функцию-член

Node *newNode(int data);

следует удалить. В свою очередь эту публикуемую c функцию-член

Node* insertEnd(Node* head, int data);

следует объявить как

void insertEnd( int data );

Если это требуется (но не обязательно), функция может вызывать закрытое состояние c функция-член объявлена ​​как

static Node* insertEnd(Node* head, int data);

Поскольку вы объявили двусторонний односвязный список, то не имеет смысла определять функцию insertEnd как рекурсивную функцию, потому что нет рекурсии. Новый узел добавляется к узлу, который вы назвали как trailer, хотя было бы лучше назвать его как tail.

Более того, в определениях функций newNode и insertEnd вы забыли указывать имя класса Inventory вроде

Node * Inventory::newNode(int data)
{
    //...
}

Node * Inventory::insertEnd(Node* head, int data)
{
    //...
}

И эта часть в основном

Inventory inventory1;

Node* head = NULL;

head = inventory1.insertEnd(head, 8);
head = inventory1.insertEnd(head, 11);
head = inventory1.insertEnd(head, 20);

не имеет смысла. Объект inventory1 уже содержит элемент данных headtrailer), который должен быть обновлен для объекта.

Класс можно определить, например, следующим образом, как показано в демонстративном Программа ниже.

#include <iostream>

class Inventory
{
public:
    Inventory() = default;

    Inventory( const Inventory & ) = delete;
    Inventory & operator =( const Inventory & ) = delete;

    ~Inventory();

    void insertEnd( int data );

    void clear();

    friend std::ostream & operator <<( std::ostream &, const Inventory & );

private:
    struct Node
    {
        int data;
        Node *next;
    } *head = nullptr, *tail = nullptr;
};

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

void Inventory::insertEnd( int data )
{
    Node *node = new Node { data, nullptr };

    if ( tail == nullptr )
    {
        head = tail = node;
    }
    else
    {
        tail = tail->next = node;
    }
}

void Inventory::clear()
{
    while ( head != nullptr )
    {
        Node *node = head;
        head = head->next;
        delete node;
    }

    tail = head;
}

std::ostream & operator <<( std::ostream &os, const Inventory &inventory )
{
    for ( Inventory::Node *node = inventory.head; node != nullptr; node = node->next )
    {
        os << node->data << " -> ";
    }

    return os << "null";
}

int main()
{
    Inventory inventory;

    for ( const auto &data : { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 } )
    {
        inventory.insertEnd( data );
    }

    std::cout << inventory << '\n';

    return 0;
}

Вывод программы:

0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> null
...