我已经使用 C++ 工作了好几个星期了,但是头文件(或者我想是链接器?)背后的机制让我很困惑。我已经养成了创建“main.h”来对我的其他头文件进行分组并保持 main.cpp 整洁的习惯,但有时这些头文件会提示无法找到不同的头文件(即使它已声明在“main.h”)。我可能没有很好地解释它,所以这是我正在尝试做的事情的删节版本:
//main.cpp
#include "main.h"
int main() {
return 0;
}
-
//main.h
#include "player.h"
#include "health.h"
#include "custvector.h"
-
//player.h
#include "main.h"
class Player {
private:
Vector playerPos;
public:
Health playerHealth;
};
-
//custvector.h
struct Vector {
int X;
int Y;
int Z;
};
-
//health.h
class Health {
private:
int curHealth;
int maxHealth;
public:
int getHealth() const;
void setHealth(int inH);
void modHealth(int inHM);
};
我不会包括 health.cpp 因为它有点长(但确实有效),它确实有 #include "health.h"
.
无论如何,编译器 (Code::Blocks) 提示“player.h”找不到类型“Health”或“Vector”。我想如果我使用 #include "main.h"
进入“player.h”,它将能够找到 Health
的定义和 Vector
感觉它们包含在“main.h”中。我认为他们会通过某种方式挖隧道(player.h -> main.h -> health.h)。但这并不太奏效。是否有某种图表或视频可以阐明应如何设置? Google 没有太大帮助(我的书也没有)。
最佳答案
将头文件视为“自动复制和粘贴”的最佳方式。
考虑它的一个好方法(虽然不是实际实现的方式)是当您编译 C 文件或 C++ 文件时,预处理器首先运行。每次遇到#include 语句时,它实际上都会粘贴该文件的内容,而不是#include 语句。这样做直到没有更多的包含。最终缓冲区被传递给编译器。
这引入了几个复杂性:
首先,如果 A.H 包含 B.H 而 B.H 包含 A.h,那么您就有问题了。因为每次你想粘贴 A 时,你都需要 B 并且它内部会有 A !那是一个递归。为此,头文件使用#ifndef,以确保同一部分不会被多次读取。这很可能发生在您的代码中。
其次,您的 C 编译器会在所有头文件都已“扁平化”后读取该文件,因此在推理在什么之前声明什么时,您需要考虑这一点。
关于c++ - 有人可以帮助阐明头文件的工作原理吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3098281/