Spent too much time commenting and not answering. This is pretty much what Bolov showed, but with more of the gory details.
Let's looks at this the way the compiler does. Whenever the compiler, really the preprocessor, finds an include
directive, it replaces the include
with the content of the included file.
The compiler starts with Main.cpp. It sees the
#include "FileA.h"
and replaces it with FileA.h so now you have
#include "FileB.h"
class FileA{
private:
FileB* b; //It doesn't give error here!
};
The compiler picks up where it left off and finds
#include "FileB.h"
and replaces it with FileB.h. Now you have
class FileB{
private:
FileA* A; //The error is here!
};
class FileA{
private:
FileB* b; //It doesn't give error here!
};
No more preprocessor work is required, so the compiler looks at the combined file. FileB
is the first thing defined, and it needs a declaration of FileA
to satisfy FileA* A;
. The compiler hasn''t seen FileA
yet, so it emits an error and keeps going. It finds FileA
and the FileB* b;
member, but at this point it's seen FileB
, so no error.
When you have a pointer or reference it's enough for the compiler to know that the identifier exists, even if it doesn't know what the named type looks like, because it doesn't have to hold an instance of the type. The fix is to forward declare FileA ahead of
FileB`
class FileA; // forward declaration
class FileB{
private:
FileA* A; //The error is here!
};
class FileA{
private:
FileB* b; //It doesn't give error here!
};
Now FileA* A;
is satisfied that there is such a thing as a FileA
It doesn't know enough to construct one or how to access anything inside a FileA
yet, but no one has asked it to.
This resolves to a FileB.h that looks like
class FileA; // forward declaration
class FileB{
private:
FileA* A; //The error is here!
};
Bolov makes a very good point about preventing multiple includes of the same file. Sometimes you can get away with it, but often you wind up with recursive loops and nigh-inscrutable error messages. Best to be avoided with your choice of Include Guard mechanism.