не могу соединить мой заголовочный файл с моим cpp-файлом в связанном списке - PullRequest
0 голосов
/ 28 июня 2019

Предполагается, что определение и библиотеки работают, т.е.<iostream>, <cassert>, #define__NODE_H__ и т. Д.

Вопрос: как вставить узел в заголовок (часть 1) и вставить данные в заголовок (часть 2)?

Мой файл заголовка (часть 1):

class Node {
     public:
         typedef int nodeDatatype;

         Node(
             const nodeDatatype& initData = nodeDatatype(),
             Node* initLink = NULL)
         {data = initData; link = initLink;}

         void setData(const nodeDatatype& new_data) {data = new_data;}
         void setLink(Node* new_link)               {link = new_link;}

         nodeDatatype getData() const {return data;}

         const Node*  getLink() const {return link;}
               Node*  getLink()       {return link;}

     private:
         nodeDatatype data;
         Node* link;
};
void insertHead(Node*& head, Node*& entry);

Моя функция файла реализации (часть 1):

Node* insertHead(Node *head, Node *entry){
     Node* newNode = entry;
     newNode->setData = setData;
     newNode -> next = NULL;
     if(head == NULL){
         head = newNode;
     }
     else{
         newNode->next = head;
         head = newNode;
     }
     return head;
     }

Это правильно?Или я предполагаю добавить Node::Node* область?

Для части 2, я могу просто вставить данные с той же функцией, что я использую для вставки узла в заголовке?Или оно должно быть отдельным?

Я получаю ошибку:

не объявляется в области действия

Ответы [ 2 ]

1 голос
/ 29 июня 2019

Мне кажется, что требования в дополнение к

void insertHead(Node*& head, Node*& entry);

вам понадобится

void insertHead(Node*& head, const Node::nodeDatatype & data);

ссылка, чтобы избежать копирования data (что-то бессмысленное с int, но typedef может быть изменено на что-то более правильное) и const, потому что insertHead не имеет смысла изменять данные. Const также позволяет функции принимать более широкий спектр типов переменных.

Эта перегрузка insertHead должна была бы создать Node для хранения данных, и после этого можно вызвать Node, принимающий insertHead. Например:

void insertHead(Node*& head, const Node::nodeDatatype & data)
{
    Node * newNode = new Node(data);
    insertHead(head, newNode);
} 

Это все основано на

void insertHead(Node*& head, Node*& entry);

выполняется правильно, и в настоящее время это не так. Давайте исправим это, так как исправление действительно простое.

Node* insertHead(Node *head, Node *entry){

не соответствует объявлению. Используйте

void insertHead(Node*& head, Node*& entry){

вместо этого. Остальная часть функции в основном делает то, что вы хотите, но делает это очень окольным образом.

     Node* newNode = entry;

не требуется. это не приносит никакого вреда, но давайте все равно потрошим и будем использовать запись на всем протяжении.

     newNode->setData = setData;

что такое setData? Что не так с данными уже в узле?

     newNode-> next = NULL;
     if(head == NULL){
         head = entry;
     }
     else{
         newNode->next = head;
         head = newNode;
     }

Нет необходимости в большинстве вышеперечисленных. Новый узел идет впереди head, поэтому нет необходимости проверять, является ли head нулевым или нет, просто укажите для next нового узла то же самое, что и head. Другими словами, всегда делайте иначе.

     return head;

Раньше это имело смысл, но теперь после сопоставления определения и объявления. Не возвращайте значение из void функции.

}

Мы заканчиваем с

void insertHead(Node*& head, Node*& entry){
    entry->next = head; 
    head = entry; 
}

Объединяя все это, мы получаем,

class Node {
     public:
         typedef int nodeDatatype;

         Node(
             const nodeDatatype& initData = nodeDatatype(),
             Node* initLink = NULL)
         {data = initData; link = initLink;}

         void setData(const nodeDatatype& new_data) {data = new_data;}
         void setLink(Node* new_link)               {link = new_link;}

         nodeDatatype getData() const {return data;}

         const Node*  getLink() const {return link;}
               Node*  getLink()       {return link;}

     private:
         nodeDatatype data;
         Node* link;
};
void insertHead(Node*& head, Node*& entry);
void insertHead(Node*& head, const Node::nodeDatatype & data);

А потом реализации

void insertHead(Node*& head, Node*& entry){
    entry->link = head; // this line is currently impossible due to link being private
                        // perhaps these functions should be reworked into members
    head = entry; 
}
void insertHead(Node*& head, const Node::nodeDatatype & data)
{
    Node * newNode = new Node(data);
    insertHead(head, newNode);
} 

Sidenote: Вместо typedef int nodeDatatype; рассмотрите возможность сделать класс шаблоном.

0 голосов
/ 29 июня 2019

Какую версию c ++ вы используете? Попробуйте настроить в Wandbox или что-то. Так что вы можете легко скопировать точные сообщения в свой вопрос.

Некоторые комментарии:

Ошибка

  • используйте std::shared_ptr<> не сырые указатели. Вы получите что-то не так, если будете использовать необработанные указатели.
  • insertHead() должен быть либо функцией-членом, либо функцией-другом, на данный момент это не то и другое Я предполагаю, что это должна быть функция-член.
  • что такое ->setData ??
  • что такое ->next ??
  • написать несколько тестов для insertHead(), чтобы охватить различные ситуации (каждая половина if и т. Д.)
  • просто использование int для ваших данных покроет некоторые ошибки, когда вы перейдете к использованию реальных данных. Используйте шаблон, чтобы избежать этого.

Style

  • использовать nullptr не NULL
  • используйте using nodeDataType = int или template<T=int> не typedef int nodeDataType
...