在'{'标记类继承之前的c ++期望的类名

时间:2012-12-27 13:29:30

标签: c++ inheritance

  

可能重复:
  error: expected class-name before ‘{’ token

我有一个主要的超类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 */

4 个答案:

答案 0 :(得分:4)

你有一个循环包含。从GameObject.h中删除这一行:

#include "GuiBitMapText.h"

你不在GameObject.h中使用这个类,所以不需要包括甚至在那里。在某些情况下,您必须在处理其定义相互引用的类型时转发声明类,但由于GameObject未对GuiBitMapText进行任何引用,因此您没有理由需要转发 - 在这个例子中声明。

答案 1 :(得分:1)

你有一个循环包含。考虑何时编译包含GameObject.h(例如GameObject.cpp)的内容。将包含GameObject.h,其中GuiBitMapText.h包含GameObject的定义,然后在GameObject.h的定义之上包含GuiBitMapText。但是,你的包含守卫会阻止最后一次包含实际做任何事情,因此GuiBitMapText将无法编译,因为GameObject之前没有定义。

GameObject甚至不依赖于GuiBitMapText,因此没有理由让#include "GuiBitMapText.h"出现。只是摆脱它,你会没事的。

答案 2 :(得分:0)

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

您应该知道何时实际包含标题以及何时使用转发声明。

对于GameObject,它实际上根本没有外部依赖。您的头文件无需包含任何其他标头。

对于GuiBitMapText:

  • 这是一种GameObject。要从类派生,您必须包含其标题(您有)。因此,请保留#include GameObject.h
  • 您的班级有一个字符串作为成员。所以你需要<string>的标题
  • 您的班级有一个指向BMF的指针。前瞻性声明就足够了。删除包含可能会破坏某些代码,而这些代码期望包括在那里但修​​复该代码,而不是此文件。将#include "BMF.h"替换为class BMF;
  • 您的类有一个指向SDL_Texture的指针。不仅如此,此指针仅出现在类的私有部分中,并且根本不出现在公共接口中。 (与公共构造函数中出现的BMF指针以及类成员不同)。所以在这里你应该使用前瞻声明。然后,您班级的用户不会获得包含的开销。将"#include SDL.h"替换为class SDL_Texture;

这是一个有用的东西,可以在将来以及在这种特殊情况下为您提供帮助。

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

答案 3 :(得分:-1)

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

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

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