Drew Drew - 2 months ago 9
C++ Question

How many other files does include affect aside from the one it's in?

I'm just learning C++, and I was under the presumption that including something would only affect the file that included it, but I appear to be wrong. My setup is like so:

enter image description here

If I don't include BaseClass.h in either Main or Subclass (extends BaseClass), I get an seemingly-normal error telling me I can't use BaseClass in Subclass because it doesn't exist. If I include BaseClass.h in Subclass.h, everything works fine. If I don't include BaseClass.h in Subclass.h, but I include it in the main cpp, it also works fine? At first I thought this meant including something in one file included it for the whole project, but I'm not sure about that because BaseClass.cpp included BaseClass.h this whole time and I got an error when it wasn't included in main/Subclass.

Why am I able to interchange inclusion of BaseClass.h between the main cpp and Subclass.h while having it function in both cases? How many files are affected when I include something?

I'm working in Eclipse Neon with a MinGW GCC project, but I'm not sure if that affects the behavior. Here is the source code I'm working with:

The main 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() {}
};

Answer

The effect of #include is as if the referenced file's contents completely replace the #include statement itself.

Your Subclass class is derived from Baseclass. The subclass.h header file declares Subclass, therefore when compiling subclass.h, the definition of Baseclass must be available.

Except, and this is the key point, you do not exactly compile subclass.h. You are compiling RetroProject.cpp. This is what your compiler is actually compiling. Or, rather, begins compiling.

Your compiler starts compiling RetroProject.cpp, reading the file from its beginning to its end. Each time it encounters a #include, the referenced file's contents completely replace the #include statement, and the compiler then resumes reading and compiling the code, starting with the #included text. When it sees another #include, the process repeats.

So, if you have a #include "baseclass.h" in subclass.h, then the following happens. When your RetroProject.cpp #includes subclass.h, the contents of subclass.h replace the #include statement in RetroProject.cpp, then, the compiler resumes compiling, it sees another #include, and then it replaces that #include with the contents of baseclass.h.

The compiler then parses baseclass.h, which defines the BaseClass, and then it compiles the rest of subclass.h, which defines SubClass, and since BaseClass is already defined, there is no issue.

If you explicitly #include the baseclass.h file in retroproject.cpp, then the compiler first replaces that #include with the contents of baseclass.h, compiles it, defines the BaseClass, then the #include of the subclass.h file gets processed the same away, and, once again, everything that should be defined, is defined.