除了它所在的文件外,include 还会影响多少其他文件?

3

我正在学习C++,我原以为包含某些内容只会影响到包含它的文件,但是我似乎错了。我的设置如下:

enter image description here

如果我在Main或Subclass(扩展BaseClass)中都不包含BaseClass.h,那么当我在Subclass中使用BaseClass时,会出现一个看似正常的错误提示我不能使用BaseClass,因为它不存在。如果我在Subclass.h中包含BaseClass.h,一切都正常工作。如果我不在Subclass.h中包含BaseClass.h,但我在主cpp中包含它,也可以正常工作?起初,我以为这意味着在一个文件中包含某些内容会将其包括在整个项目中,但我对此并不确定,因为BaseClass.cpp一直包含BaseClass.h,当它未包含在main/Subclass中时,我会得到一个错误。

为什么我能够在主cpp和Subclass.h之间交替包含BaseClass.h,同时使其在两种情况下都起作用?当我包含某些内容时,有多少文件受到影响?

我正在使用Eclipse Neon和MinGW GCC项目,但我不确定它是否会影响行为。这是我正在使用的源代码:

主cpp,ReproProject.cpp:

#include <iostream>
#include "BaseClass.h"
#include "Subclass.h"

using namespace std;

int main() {
    Subclass s;
    cout << "Hello World!" << endl; // prints !!!Hello World!!!
    return 0;
}

BaseClass.h

#pragma once

class BaseClass
{
public:
    BaseClass();
};

BaseClass.cpp

#include "BaseClass.h"

BaseClass::BaseClass()
{

}

Subclass.h

#pragma once

class Subclass: public BaseClass
{
public:
    Subclass() : BaseClass() {}
};

简化来说,您可以这样看待:对于每个编译单元,预处理器将使用所包含文件的内容替换每个 #include 指令。完成后,您基本上会得到一个巨大的源代码文件,其中包含所有已包含的代码。然后将其传递给编译器执行其工作。 - Dan Mašek
2个回答

2
#include的作用是,引用文件的内容完全替换#include语句本身。 您的Subclass类是从Baseclass派生的。因此,在编译subclass.h时,必须提供Baseclass的定义。但是实际上,您并没有直接编译subclass.h,而是编译RetroProject.cpp。编译器从头到尾阅读RetroProject.cpp文件,并在遇到#include时将引用文件的内容完全替换#include语句。如果subclass.h中有#include "baseclass.h",则编译器会首先将#include "baseclass.h"替换为baseclass.h中的内容,然后继续解析代码。如果您显式地在retroproject.cpp#include baseclass.h文件,则编译器首先编译baseclass.h,定义BaseClass,然后处理subclass.h文件。

0
如果你在SubClass.h中包含了BaseClass.h,然后在主cpp文件中包含了SubClass.h,那么它将会随之包含BaseClass.h。这回答了你的问题吗?

不,那个是有效的并且是我在问题中提到的测试案例之一,但我很好奇为什么我也能在主 cpp 中包含 BaseClass.h 并且仍然有 SubClass 函数,即使它没有包含 BaseClass。 - Drew

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接