3

所以我有三个有关文件:

MyGame.cpp        //Where all my codeing takes place
MyDirectX.h       //Where I declare prototypes
MyDirectX.cpp     //where I define functions/structs 

我有一个不错的小结构,看起来像这样:

struct Sprite
{
LPDIRECT3DTEXTURE9 texture;

int frame;
int starttime;

    Sprite()
    {
        texture = NULL;
        texture = LoadTexture("explosion_30_128.tga");
        frame = 0;
        starttime = 0;
    }
};

所以这里的问题是:

当我在 MyGame.cpp 中声明该结构时,它工作得很好。但是,我需要在我的头文件中使用它,因为其他功能依赖于它(并且为了整洁)。我在 MyDirectX.h 中这样声明它:

struct Sprite;

并在 MyDirectX.cpp 中定义:

struct Sprite
{...code...};

我可以在 MyGame.cpp 中创建一个全局 Sprite

Sprite explosion;

所有检查。但是当我尝试explosion.frame = 或explosion->frame =(或任何其他成员)时,我收到错误“表达式必须是指向完整对象类型的指针”。

如果我在 MyDirectX.h 而不是 MyDirectX.cpp 中定义整个结构,我会得到一个未解析的外部符号。如果我在两者中都进行了定义,则会出现重新定义错误。

我已经做了几个小时的测试和研究,但我无法弄清楚这一点。对我来说,为什么该结构可以在 MyGame.cpp 中工作但在我的头文件中使用它时不起作用,这对我来说毫无意义。我应该注意,我已经在这些文件中声明并定义了许多函数,它们都工作得很好。

任何帮助将非常感激。谢谢。

4

3 回答 3

3

Sprite sprite;定义,而不是声明。它尝试创建该对象。要声明类,只需添加struct Sprite;.

要拥有全局,您需要使用extern Sprite sprite,否则,在多个翻译单元中包含该标题时,您将收到多重定义错误。

于 2013-02-21T20:01:59.843 回答
3

您需要将完整的定义放在struct标头中,以便可以通过完整类型的任何代码访问它:

struct Sprite
{
  LPDIRECT3DTEXTURE9 texture;

  int frame;
  int starttime;

  Sprite();

};

然后,您可以将实现代码放在单独的.cpp文件中。对于不需要完整类型的代码,可以继续使用前向声明

struct Sprite;
于 2013-02-21T20:02:18.537 回答
2

错误“表达式必须是指向完整对象类型的指针。” 意味着您只转发声明了一个对象,但没有提供定义,因此“不完整”。

前向声明,即

struct Sprite;

让您:
1) 将变量存储/传递为 Sprite*
2) 将变量存储/传递为 Sprite&

您不能做任何其他事情,即调用函数或访问 Sprite 的成员。

要完成这些事情,您需要定义,即

struct Sprite
{
  LPDIRECT3DTEXTURE9 texture;

  int frame;
  int starttime;

  Sprite();

};

因此,如果另一个 .cpp 文件正在使用 Sprite,则必须将定义放在一个标头中,并使用 sprite 将该标头包含在 .cpp 中。

于 2013-02-21T23:26:37.520 回答