Why do I need to use forward declarations for a class when I am already including the relevant header file? It has fixed my problem but confused me!
essentially clas
A viceversa relation between classes always needs at least one forward declaration. You can define only a class at a time, so when you define the first class the second is undefined so far. Including headers is not enough, because those headers should also be including each others. Including a file is no different than pasting its contents at the include location. With that in mind, how would you declare two classes that refer to each other within a single file? The answer, as you already know, is forward declarations.
If you have a circular declaration dependence, you'll probably have something like this:
A.h
defined class A
and starts with #include "B.h"
B.h
defined class B
and starts with #include "A.h"
Now, your header files will have include guards, so they're only included once. So in the context of B.h
, there's only a single inclusion of A.h
, so you'll get something that's effectively like this:
class A { B * bp; }; // from `#include "A.h"`
class B { A * ap; };
Now you're stuck, because the first line is incorrect without having the declaration of B
. You fix this by adding a forward declaration to A.h
:
// A.h
#ifndef H_A
#define H_A
class B;
class A { B * bp; };
#endif
When you have a circular include dependency, and you're properly using include guards (as you clearly are), then since there isn't an infinite circular include, the compiler has to stop at some point, and it doesn't know about the contents of the other header. When you add the forward declaration it's able to compile your code.
For example, A
includes B
. Then B
includes A
, but A
' include guard kicks in and prevents it from being evaluated a second time. Then it drops back into B
which doesn't know about anything from A.h
at that point because the include guard prevented its inclusion. The forward declaration however doesn't have any include guards around it so it proceeds as normal.
There's nothing inherently wrong with circular dependencies, but I do always suggest taking a second look at your design to see if factoring out logic into a third class is possible. Forward declarations are the C++ mechanism to prevent infinitely circular dependencies.