2015-09-02 2 views
0

Я пытаюсь написать файлы реализации класса и структуры. Класс имеет переменные из структуры. Я продолжаю получать ошибки:Ошибка компилятора: ошибка: «ListNode» не называет тип

LinkedList.h: 70: 8: error: 'ListNode' не называет тип ListNode * head;

LinkedList.h: 71: 8: error: 'ListNode' не называет тип ListNode * cursor;

LinkedList.h выглядит следующим образом:

#ifndef CLASS_LINKEDLIST_H 
#define CLASS_LINKEDLIST_H 

// Header files 

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

using namespace std; 

class LinkedList 
    { 
    public: 
    LinkedList(int maxSize = 10); 
    LinkedList(const LinkedList& other); 
    ~LinkedList(); 

    private: 

     ListNode* head; 
     ListNode* cursor; 

     int capacity; 
     int size; 
    }; 

#endif // ifndef CLASS_LINKEDLIST 

ListNode.h это структура, как это:

#ifndef STRUCT_LISTNODE_H 
#define STRUCT_LISTNODE_H 

using namespace std; 

struct ListNode 
    { 
    ListNode(int nodeData, ListNode* nextPtr); 
    int dataItem; 
    ListNode* next; 
    }; 
#endif // STRUCT_LISTNODE_H 

ListNode.cpp выглядит следующим образом:

#ifndef STRUCT_LISTNODE_H 
#define STRUCT_LISTNODE_H 

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

ListNode:: ListNode(int nodeData, ListNode* nextPtr) 
    { 
    dataItem = nodeData; 
    next = nextPtr; 
    } 

#endif // STRUCT_LISTNODE_H 

И здесь является верхней частью LinkedList.cpp

#ifndef STRUCT_LISTNODE_H 
#define STRUCT_LISTNODE_H 

// header files 
#include "LinkedList.h" 

Мне не разрешено изменять файлы .h, только те .cpp. Я знаю, что есть что-то простое, что я забываю включить, но я не могу понять это.

Благодарим за любую помощь заранее.

+1

Почему у * LinkedList.cpp * есть защитники? Включен ли он в другой файл? –

+4

Да, удалите включенные стражи из ваших файлов CPP. Включить охранники - это обычно строки, которые говорят '#ifndef filename_h'. –

+0

Это домашнее задание, и вам были предоставлены файлы заголовков? Если это так беспокоит, что они используют 'namespace std;' в заголовках ... 'using namespace' в заголовках - плохая идея. –

ответ

0

Включить защиту размещены так, что если файл включается несколько раз, он используется только один раз.

Когда вы включаете файл, он, для всех намерений и целей, копировать-вставить в том числе файл, так препроцессора компилятора, ListNode.cpp выглядит следующим образом:

#ifndef STRUCT_LISTNODE_H 
#define STRUCT_LISTNODE_H 

#ifndef STRUCT_LISTNODE_H 
#define STRUCT_LISTNODE_H 

using namespace std; 

struct ListNode 
    { 
    ListNode(int nodeData, ListNode* nextPtr); 
    int dataItem; 
    ListNode* next; 
    }; 
#endif // STRUCT_LISTNODE_H 
#include <iostream> //contents of iostream go on for pages. Let's skip those, shall we? 

ListNode:: ListNode(int nodeData, ListNode* nextPtr) 
    { 
    dataItem = nodeData; 
    next = nextPtr; 
    } 

#endif // STRUCT_LISTNODE_H 

Ломать что вниз компилятор видит:

#ifndef STRUCT_LISTNODE_H 

Если STRUCT_LISTNODE_H не был определен, сделать все вплоть до соответствующего #endif.

#define STRUCT_LISTNODE_H 

Прохладный. STRUCT_LISTNODE_H только что определен.

#ifndef STRUCT_LISTNODE_H 

На этот раз STRUCT_LISTNODE_H было определено, поэтому мы пропускаем вниз к соответствующему ENDIF:

#endif // STRUCT_LISTNODE_H 

Это верно, заголовочный файл был почти полностью отброшен. Так что же будет скомпилирован является:

#ifndef STRUCT_LISTNODE_H 
#define STRUCT_LISTNODE_H 

#ifndef STRUCT_LISTNODE_H 
#endif // STRUCT_LISTNODE_H 
#include <iostream> //contents of iostream go on for pages. Let's skip those, shall we? 

ListNode:: ListNode(int nodeData, ListNode* nextPtr) 
    { 
    dataItem = nodeData; 
    next = nextPtr; 
    } 

#endif // STRUCT_LISTNODE_H 

Там нет никаких признаков определения ListNode «s.

Так что это не так много, что используемые OP включают в себя защитники в файле cpp (и файл cpp никогда не должен включаться, поэтому включить стражи необязательно), но этот OP использовал тот же самый защитник дважды.

Как объявление об общественном обслуживании, обычное предупреждение о using namespace std; Эта небольшая короткая ссылка вытаскивает всю стандартную библиотеку в глобальное пространство имен. Это означает, что если у вас есть функция с именем reverse, ей теперь нужно бороться с std::reverse, и вам может не понравиться, кто победит и что это делает с выполнением вашей программы.

Так что хорошо. Ваш код в порядке с этим, но что, если вы включаете чужой? Теперь они конфликтуют с именами, которые они не намеревались, и у вас есть странные сообщения об ошибках, которые они никогда не видели и, вероятно, не могут вам помочь.

Используйте его экономно. Либо префикс с станд ::

std::cout << "HI!" << std::endl; 

или только тянуть части, нужно в глобальное пространство имен

using std::cout; 
using std::endl; 

, а затем

cout << "HI!" << endl; 

Самое главное сделать это последний после включения всех остальных заголовок файлы, потому что вы не знаете, как они будут реагировать. Но это твоя проблема для лени. Высасывает тебя.

И это подводит нас к тому, почему вы не ставите using namespace std; в заголовок. Некоторые бедные присоски включают ваш заголовок, чтобы использовать вашу библиотеку. БУМ! Они наследуют ваш плохой стиль кодирования. Они страдают за ваши ошибки. Это не круто.

Смежные вопросы