【问题标题】:error C2143 : missing ';' before '*'错误 C2143:缺少“;”前 '*'
【发布时间】:2011-10-03 08:21:57
【问题描述】:

你好,我已经在互联网上到处寻找答案,但我找不到任何答案。

代码:

#ifndef GAME_H
#define GAME_H

#include "drawEngine.h"
#include "sprite.h"
#include <iostream>
using namespace std;

class Game
{
public:
    bool run(void);

protected:
    bool getinput(char *c);
    void timerUpdate(void);

private:
    Sprite* player; // this gives me C2143

    double frameCount;
    double startTime;
    double lastTime;

    int posx;
    //int posy;
    DrawEngine drawArea;
};

#endif

我该如何解决这个问题?

精灵.h

#ifndef GAME_H
#define GAME_H
#include "drawEngine.h"
#include "game.h"

enum
{
    SPRITE_CLASSID,
};
struct vector
{
    float x;
    float y;

};

class Sprite
{
public:


    Sprite(DrawEngine *de, int s_index, float x = 1, float y = 1, int i_lives = 1);
    ~Sprite();
    vector getPosition(void);

    float getX(void);
    float getY(void);

    virtual void addLives(int num = 1);
    int getLives(void);
    bool isAlive(void);

    virtual bool move(float x, float y);

protected:

    DrawEngine *drawArea;
    vector pos;
    int spriteIndex;
    int numLives;
    int classID;
    vector facingDirection;
    void draw(float x, float y);
    void erase(float x, float y);

private:
};

#endif

【问题讨论】:

  • 我们可能需要看到`sprite.h"的内容才能对此进行智能评论。
  • 可能是命名空间下的Sprite 类?
  • 该错误意味着Sprite 不是全局命名空间中的类名。 Sprite 没有在任何地方声明(也许您在 sprite.h 中有错字?),或者它在命名空间中声明,在这种情况下,您需要将其完全限定为 TheNamespace::Sprite 或添加 using 声明。
  • @Joachim Velzel:不要使用using namespace std,尤其是在头文件中!

标签: c++ visual-studio-2010


【解决方案1】:

这种情况下的问题似乎是Sprite 未被识别为类型。仔细看后,你遇到的问题是你定义:

#ifndef GAME_H
#define GAME_H
//...
#endif

在两个文件中。您可以在 .cpp 文件(或 Game.h 文件..第一个代码 sn-p)中执行此操作,并且您也在 Sprite.h 文件中执行此操作。问题是,在编译器转到 Sprite.h 时,GAME_H 已经定义,因此,由于#ifndef 例程,它不再编译 Sprite.h 文件。

要修复它,请在 Sprite.h 文件中更改如下:

#ifndef SPRITE_H
#define SPRITE_H
//...
#endif

【讨论】:

  • 对于遇到类似错误并通过 google 来到这里的任何人:循环包含(在这种情况下,如果 Sprite.h 还包括 Game.h)也可能导致此问题。因为在 Sprite 的定义之前可以到达 Game::player 的定义,所以 Sprite 再次不被识别为类型。
【解决方案2】:

我猜这是来自 Sprite.cpp 的编译。

Sprite.cpp 包含 sprite.h,其中包含顶部的 game.h。后者 include 再次包含 sprite.h,由于它的包含保护或 pragma 一次,它什么也不做。这意味着,那时还没有已知的名为 sprite 的类——就像在这个编译中一样,它在它的下面。

生成的代码(预处理后,编译前)如下所示:

class Game { Sprite *... };

class Sprite { ... };

Sprite::func() {};

本质上,您无法轻松解决此问题。您需要使其中一个标题不依赖于首先包含的另一个标题。你可以这样做,每次你不需要类的内容,转发声明它而不是包含它。

class Game;
class Sprite {...};

class Sprite;
class Game { Sprite *...};

所以如果你这样做然后编译 sprite.cpp,预处理后的输出将看起来像

class Sprite;
class Game { Sprite *... };
class Sprite { ... };
Sprite::func() {};

这将起作用。在您声明指向 Sprite 的指针时,编译器不需要知道它到底是什么。事实上,唯一需要完整声明的情况是:

  • 你使用类的成员
  • 你从类继承
  • 你在类上使用 sizeof
  • 你用它实例化一个模板

就是这样。可能还有更多,但它们不会是常见的情况,您不应该那么快遇到它们。在任何情况下,首先使用前向声明,如果确实不起作用,则包含标题。

【讨论】:

    【解决方案3】:

    You need to declare it as a friend in that namespace.

    class Game
    {
        friend class Sprite;
    
    public:
       ...
    

    【讨论】:

    • 没有他/她不会,除非 OP 的情况与其他问题相同,我在这里通过推测并意识到我删除了我的答案树立了一个坏榜样。猜测可能会导致新手做出某些错误的假设。
    • 我是根据经验说话的,我自己之前曾在第 7.3.1.2 节中绊倒过。
    • 发布的内容不需要特权访问,可能只是sprite.h中的错误。
    • 当然,您的经验非常宝贵,并且很可能 OP 遇到的问题与您提到的相同,但如果不是,OP 会做出一些毫无根据的假设。只是添加它不是我的反对意见。不是投反对票的人。
    • 你真的不需要友元声明就能声明一个指针,除非它是另一个类的私有内部类。如果是这样,那么你需要和那个类成为朋友,而不是 sprite。
    猜你喜欢
    • 2012-02-22
    • 2013-07-30
    • 2011-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多