单独编译中未声明的标识符
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,以便编译器在您开始使用它之前知道它是什么。
自从我上次使用单独的编译编码以来已经有一段时间了,所以我有点尴尬,我不知道是什么导致了这样一个基本的错误。
这是我的 "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,以便编译器在您开始使用它之前知道它是什么。