编译器错误C2653:不是类或命名空间名称。

24

最近我在使用Visual C++ 2012时遇到了一个非常令人沮丧的问题。直到几个小时前,我一直能够正常编写代码并且一切都按照预期运行,直到我决定对一些内容进行优化并删除了一些类。我已经修复了由此引起的所有错误,例如错误的包含等等。不幸的是,之后VS编译器开始出现各种错误,例如:

Error 14 error C2653: 'Class' : is not a class or namespace name

或者甚至更多

Error 5 error C2143: syntax error : missing ';' before '}'
Error 4 error C2059: syntax error : '>'

我已经检查了多次,一切都在正确的位置:所有头文件都被包含了,所有符号也都放在了它们应该在的地方。

据我所知,问题不在我的代码上,而是与编译器本身有关......Visual Studio 有时可能真的很烦人。无论如何,如果有人能帮我解决这个问题,我会非常感激。

(顺便说一下,禁用预编译头文件并没有起作用)

相关代码片段:

Error 14:

#include "PlayerEntity.h"
PlayerEntity::PlayerEntity(void) {} // This line causes the error

错误5:

class GameScreen : public BaseScreen
{
public:
    ...
private:
    ...
}; // This line causes the error

错误 4:

private:
     std::vector<BaseEntity*> _EntityList; // This line causes the error

整个PlayerEntity.h文件:

#ifndef PENTITY_H
#define PENTITY_H

#include "BaseEntity.h"

class PlayerEntity : public BaseEntity
{
public:
    PlayerEntity(void);
    PlayerEntity(float, float);
    virtual ~PlayerEntity(void);

    void render(sf::RenderWindow&);
    void update();
private:
    void init();
};

#endif

整个GameScreen.h文件:

#ifndef GSCREEN_H
#define GSCREEN_H

#include "BaseScreen.h"
#include "BaseEntity.h"
#include "PlayerEntity.h"

class GameScreen : public BaseScreen
{
public:
    GameScreen(sf::Vector2u&);
    virtual ~GameScreen(void);

    void start();
    void stop();

    void render(sf::RenderWindow&);
    void update(void);

    void addEntity(BaseEntity*);
    void destoryEntity(int id);
private:
    std::vector<BaseEntity*> _EntityList;
    sf::Vector2u _ScreenDimensions;
};

#endif

整个 BaseEntity.h 文件:

#ifndef BSENTITY_H
#define BSENTITY_H

#include "Input.h"
#include <SFML/Graphics.hpp>

class BaseEntity
{
public:
    BaseEntity(void);
    virtual ~BaseEntity(void);

    sf::Vector2f position;

    virtual void update(void);
    virtual void render(sf::RenderWindow&);
    void compare(BaseEntity*);
protected:
    sf::Texture *_EntityTexture;
    sf::Sprite  _EntitySprite;

    bool _isAlive;
    int  _id; 

    virtual void init();
};

#endif

整个Input.h文件:

#ifndef INPUT_H
#define INPUT_H

#include "ScreenSystem.h"
#include <SFML/Window.hpp>

class Input
{
public:
    Input(void);
    Input(sf::RenderWindow*);
    virtual ~Input(void);

    static bool keyPressed(int);
    static bool keyReleased(int);

    static bool mouseHeld(int);
    static bool mouseReleased(int);
private:
    static sf::RenderWindow *_Window;
};

#endif

整个ScreenSystem.h文件:

#ifndef GHANDLER_H
#define GHANDLER_H

#include "BaseScreen.h"
#include "MenuScreen.h"
#include "GameScreen.h"
#include <SFML/Window.hpp>

class ScreenSystem
{
public:
    ScreenSystem(void);
    ScreenSystem(sf::RenderWindow*);
    virtual ~ScreenSystem(void);

    BaseScreen *getCurrentScreen(void);
    void setScreen(int);
private:
    int _currentScreenID;

    std::vector<BaseScreen*> _Screens;
    sf::RenderWindow *_Window;
};

#endif

4
我怀疑这不是编译器本身的问题。 - Joseph Mansfield
2
请提供一个「短小、自包含、正确」的示例(SSCCE)。 - Oswald
@WhozCraig已经做了,这些都是虚假错误。在实际代码中不存在任何一个。 - valtari
4
一般建议:始终修复你得到的第一个错误,而不是由第一个错误导致的其他错误。第一个错误可能会让编译器困惑,所有随后的错误可能都是误报的。在你没有修复第一个错误之前,忘记第4、5和14个错误。 - Daniel Frey
2
@Jakobson:经常涉及到缺少 ; 的错误往往是编译器遇到无法识别的标记(比如,一个尚未声明的类名)的症状。 - jamesdlin
显示剩余21条评论
2个回答

55
您的头文件存在循环依赖。 BaseEntity.h 包含了 Input.hInput.h 又包含了 ScreenSystem.hScreenSystem.h 又包含了 GameScreen.h,而 GameScreen.h 再次包含了 BaseEntity.h,导致在声明前使用类名,从而导致编译失败。
为避免此问题,请勿不必要地包含头文件。例如,请勿在 BaseEntity.h 中包含 Input.h,因为它根本不需要;也请勿在 ScreenSystem.h 中包含 BaseScreen.h,因为只需要一个声明 class BaseScreen;,而不是完整的类定义。
此外,请检查是否有重复的头文件保护宏。其中一些与头文件名称不匹配(例如,ScreenSystem.hGHANDLER_H),这使我认为它们可能是意外从其他头文件中复制的。最后,不要使用保留名称,如 _EntitySprite 用于您自己的符号;为简单起见,请避免使用前导或双下划线。

3
"重复的头文件保护" - 糟糕!我花了很长时间才找到这个答案。 - cloudfeet

3

你在提问时是否将错误信息复制到了问题中,还是重新输入了一遍?因为错误14中的“Class”应该是大写C,这几乎肯定是不对的。

此外,在头文件中尽可能少使用include指令。例如,GameScreen不使用PlayerEntity,因此可以删除该包含文件,而BaseEntity仅通过指针使用,因此可以替换成

#include "BaseEntity.h"

使用前向声明

class BaseEntity;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接