单独编译中未声明的标识符

Undeclared Identifier in separate compilation

自从我上次使用单独的编译编码以来已经有一段时间了,所以我有点尴尬,我不知道是什么导致了这样一个基本的错误。

这是我的 "SpaceInvader.h" 文件中的相关代码:

#pragma once

#include "ClassDemoApp.h"
#include "SpriteSheet.h"
#include "Bullet.h"
#include <vector>

class Character{

public:
    Character(float newU, float newV, float newWidth, float newHeight, float newX, float newY, std::vector <Bullet> newVolley);

private:
    float thisU;
    float thisV;
    float thisWidth;
    float thisHeight;

    float xPos;
    float yPos;

    bool isDead;

    std::vector <Bullet> volley;
};

我在我的构造函数和私有变量声明中得到一个 C2065: 'Bullet' : undeclared identifier

郑重声明,这是我的 "Bullet.h" 文件:

#pragma once

#include "SpriteSheet.h"

class Bullet{

public:
    Bullet(float u, float v, float w, float h, const char *name);
    void normalFire();

private:
    float bulletU;
    float bulletV;
    float bulletW;
    float bulletH;

    const char *imageName;
};

我想了解我在这里做错了什么,因为我的 Bullet class is 被声明,但我不知道为什么编译器无法识别它。

您的 header 依赖项很可能存在循环。像 Bullet.h 包含 SpriteSheet.h,它包含 SpaceInvader.h,它试图再次包含 Bullet.h,它将被忽略(因为它已经被包含)。

这意味着当编译器在处理SpaceInvader.h时,它不知道Bullet是什么,因为它还没有完全处理Bullet.h

关于正在发生的事情的更多细节:当编译器命中 #include 行时,它基本上读取整个文件并将 #include 替换为文件的内容。然后它继续处理它刚刚包含的代码,它将对它找到的任何更多包含做同样的事情。如果您有两个相互包含的文件,您将以循环和编译器错误结束。

改变这种行为的一件事是 #pragma once 指令,这意味着每个 header 每次编译只包含一次。

然而,所有 #pragma once 所做的只是有效地替换任何 #include 文件的语句,这些语句已经用空白文本完成。

你可以把它想象成你在文本编辑器中,只是 cut-and-pasting 整个包含文件在 #include 行所在的位置。实际上,我建议在这种情况下这样做,看看出了什么问题 - 将原始 cpp 剪切并粘贴到一个空白文档中,然后一次用它们的文本内容替换 #include 行。如果您对已经完成的文件进行#include,只需将其删除。

因此,在您的情况下,Bullet class 的定义仍在编译器正在构建的文件中的更下方。

在这种情况下,最简单的解决方案是不包含 SpaceInvader.h 中的 Bullet.h,而只是转发声明 class。删除包含并改用此行:

class Bullet;

编辑: 注意 - 您必须在 SpaceInvader.cpp 中包含 Bullet.h,以便编译器在您开始使用它之前知道它是什么。