我只是在学习C ++,而且我认为包含某些东西只会影响包含它的文件,但我似乎错了。我的设置是这样的:
如果我在Main或Subclass中没有包含BaseClass.h(扩展BaseClass),我会得到一个看似正常的错误,告诉我我不能在Subclass中使用BaseClass,因为它不存在。如果我在Subclass.h中包含BaseClass.h,一切正常。如果我在Subclass.h中不包含BaseClass.h,但是我将它包含在主cpp中,它也可以正常工作吗?起初我认为这意味着包含一个文件包含在整个项目中的东西,但是我不确定,因为BaseClass.cpp一直包含BaseClass.h而且当它不包含在main中时我得到了一个错误/子类。
为什么我能在主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() {}
};
答案 0 :(得分:2)
#include
的效果就好像引用文件的内容完全取代了#include
语句本身。
您的Subclass
课程来自Baseclass
。 subclass.h
标头文件声明Subclass
,因此在编译subclass.h
时,Baseclass
的定义必须可用。
除了,这是关键点,你没有完全编译subclass.h
。您正在编译RetroProject.cpp
。这是您的编译器实际编译的内容。或者说,开始编译。
您的编译器开始编译RetroProject.cpp
,从开头到结尾读取文件。每次遇到#include
时,引用文件的内容都会完全替换#include
语句,然后编译器继续读取和编译代码,从#include
d文本开始。当它看到另一个#include
时,该过程会重复。
因此,如果#include "baseclass.h"
中有subclass.h
,则会发生以下情况。当您的RetroProject.cpp
#include
s subclass.h
,subclass.h
的内容替换#include
中的RetroProject.cpp
语句时,编译器将恢复编译,看到另一个#include
,然后用#include
的内容替换baseclass.h
。
然后编译器解析定义baseclass.h
的{{1}},然后编译BaseClass
的其余部分,定义subclass.h
,然后SubClass
已定义,没有问题。
如果在BaseClass
中明确#include
baseclass.h
文件,则编译器首先用retroproject.cpp
的内容替换#include
,编译它,定义baseclass.h
,然后BaseClass
文件的#include
处理相同,并且再次定义了应该定义的所有内容。
答案 1 :(得分:0)
如果在SubClass.h中包含BaseClass.h,然后在主cpp中包含SubClass.h,它将包含BaseClass.h。这会回答你的问题吗?