编译错误:Error: ' ListNode '没有命名类型

Compiler Error: error: ‘ListNode’ does not name a type

本文关键字:类型 ListNode 错误 编译 Error      更新时间:2023-10-16

我正试图编写我的类和结构实现文件。类有来自结构体的变量。我一直得到错误:

LinkedList.h:70:8: error: ' ListNode '没有命名类型ListNode *头;

LinkedList.h:71:8: error: ' ListNode '没有命名类型ListNode *光标;

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文件。我知道有一些简单的东西我忘记写了,但是我似乎想不起来。

感谢您的帮助。

设置Include保护,这样如果一个文件被多次包含,它只会被使用一次。

当您包含一个文件时,出于各种目的,它是复制粘贴到包含文件中,因此对于编译器的预处理器,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的定义。

所以这并不是说OP在一个cpp文件中使用了include守卫(一个cpp文件不应该被包括在内,所以include守卫是不必要的),而是OP使用了同一个include守卫两次。

作为一个公共服务公告,通常的using namespace std;警告这个邪恶的小快捷方式将整个标准库拉到全局命名空间中。这意味着,如果您有一个名为reverse的函数,那么它现在必须与std::reverse竞争,您可能不喜欢谁赢了,也不喜欢这会对程序的执行造成什么影响。

好了。你的代码很好,但如果你包括别人的呢?现在它们与他们不想要的名字相冲突,你会得到他们从未见过的奇怪的错误信息,可能无法帮助你。

要谨慎使用。前缀std::

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

或者只将需要的部分拉入全局命名空间

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

cout << "HI!" << endl;

最重要的是在包含其他人的头文件之后才执行此操作,因为您不知道他们将如何响应。但这是你懒惰的问题。你真倒霉。

这就引出了为什么不把using namespace std;放在标题中。一些可怜的家伙包括你的头使用你的库。哇!他们继承了你糟糕的编码风格。他们为你的错误而受苦。