C++ 在"{"标记类继承之前预期的类名

c++ expected class-name before '{' token class inheritance

本文关键字:继承 C++      更新时间:2023-10-16

可能重复:
错误:在"{"标记之前需要类名

我有一个主要的超级类GameObject和派生类GuiBitMapFont。它总是抛出预期的类名错误。但如果我将在GuiBitMapFont类GameObject中添加前向派生它抛出不完整类型"class GameObject"的无效使用"class GameObject"的前向声明

编辑是的,在GameObject文件中有#include GuiBitMapFont。但这是我写这个问题时的错误。编译器仍然抛出这两个错误。

#ifndef GAMEOBJECT_H
#define GAMEOBJECT_H
#include <string>
#include "Texture.h"
class GameObject {
private:
    int x;
    int y;
    int width;
    int height;
public:
    GameObject();
    GameObject(int x, int y, int width, int height);
    GameObject(const GameObject& orig);
    virtual ~GameObject();
    virtual void draw();
    virtual void update();
    //ignore those, i need to rewrite it....
    void setX(int x);
    void setY(int y);
    void setWidth(int width);
    void setHeight(int height);
    int getX() const;
    int getY() const;
    int getWidth() const;
    int getHeight() const;
};
#endif  /* GAMEOBJECT_H */

和衍生的

#ifndef GUIBITMAPTEXT_H
#define GUIBITMAPTEXT_H
#include <string>
#include "SDL.h"
#include "GameObject.h"
#include "BMF.h"
class GuiBitMapText : public GameObject { //error: expected class-name before '{' token
private:
    std::string text;
    BMF *font;
    //SDL_Surface *surf;
    SDL_Texture *texture;
public:
    GuiBitMapText(int x, int y, std::string text, BMF *font);
    GuiBitMapText(const GuiBitMapText& orig);
    virtual ~GuiBitMapText();
    virtual void draw();
    virtual void update();
};
#endif  /* GUIBITMAPTEXT_H */

您有一个循环include。从GameObject.h:中删除此行

#include "GuiBitMapText.h"

你没有在GameObject.h中使用这个类,所以include甚至没有必要存在。在某些情况下,当处理定义相互引用的类型时,必须转发声明类,但由于GameObject不引用GuiBitMapText,因此没有理由在该实例中转发声明。

您有一个循环包含。想想什么时候正在编译包含GameObject.h(如GameObject.cpp(的内容。将包括GameObject.h,其随后包括在GameObject的定义之上的GuiBitMapText.h,其随后包含在GuiBitMapText的定义之下的GameObject.h。但是,您的include保护将阻止最后一个include实际执行任何操作,因此GuiBitMapText将无法编译,因为GameObject在此之前没有定义。

但是GameObject甚至不依赖于GuiBitMapText,所以没有理由在那里有#include "GuiBitMapText.h"。把它扔掉,你就会好起来的。

您需要正确理解标头依赖关系。

您应该了解何时实际包含标头以及何时使用正向声明。

在GameObject的情况下,它实际上根本没有外部依赖关系。您的头文件不需要包含任何其他头文件。

在GuiBitMapText:的情况下

  • 它是一种游戏对象。若要从类派生,必须包含其标头(you have(。因此保留#include GameObject.h
  • 你的类有一个字符串作为成员。所以你也需要<string>的标题
  • 你的类有一个指向BMF的指针。提前声明就足够了。删除include可能会在某个地方破坏一些原本希望包含该include的代码,但修复了该代码,而不是该文件。将#include "BMF.h"替换为class BMF;
  • 您的类有一个指向SDL_Texture的指针。不仅如此,这个指针只出现在类的私有部分,根本不出现在公共接口中。(与BMF指针不同,BMF指针也出现在公共构造函数和类成员中(。所以这里更应该使用正向声明。那么类的用户就不会得到包含的开销。将"#include SDL.h"替换为class SDL_Texture;

这是一些有用的学习,将在未来帮助你,以及在这种特殊情况下。

将头更改为仅使用前向声明后,与这些文件相关的编译单元(即.cpp文件(现在必须包含头。

错误是由另一个文件触发的,我有两行

#include "GameObject.h"
#include "GuiBitMapText.h"

我真的不需要在那个文件中包含GuiBitMapText,所以我删除了包含GuiBitMapText,现在它可以工作了。。。