Hi I noticed if I include a header file in a .cpp
then I can create an object of that header file's class. Like if I includeA.h
in main.cpp
then I can write A *a;
in main.cpp
. But this doesn't work if I include a header file in another header file and then try to create the object of that included header file. Like,
file B.h
:
#include "A.h"
class B
{
public:
B(){};
A *a;
};
I have to add forward declaration of the class A
to make it work. Why?
Here are the basics:
For any type
A
, if you declare a variable of typeA&
,A*
,A**
,A***
,etc, then the compiler does not need to know the complete definition ofA
at the site of variable declaration. All it needs to know thatA
is a type; that is it. So a forward declaration is enough:The complete definition is not required because the compiler can still compute
sizeof(B)
which in turn depends onsizeof(A*)
andsizeof(A&)
— these are known to the compiler, even though it doesn't knowsizeof(A)
. Note thatsizeof(A*)
is just a size of pointer on that platform (which is usually4
bytes on 32bit system or8
bytes on 64bit system).For any type
A
, if you declare a variable of typeA
,A[N]
,A[M]N]
etc, then the compiler needs to know the complete definition of typeA
at the site of variable declaration. A forward declaration would not be enough in this case.But this is correct:
The complete definition is required so that the compiler could compute
sizeof(A)
, which is not possible if the compiler doesn't know definition ofA
.Note that definition of a class means "the complete specification of the class members, their types, and whether the class has virtual function(s) or not". If the compiler knows these, it can compute the size of the class.
Knowing these basics, you can decide whether to include headers to other headers or only forward declaration would be enough. If the forward declaration is enough, that is the option you should choose. Include a header only if it is required.
However if you provide forward declaration of
A
in the headerB.h
, then you have to include the header fileA.h
in the implementation file ofB
which isB.cpp
, because in the implementation file ofB
, you need to access the members ofA
for which the compiler requires the complete definition ofA
. Well again, include only if you need to access the members ofA
. :-)I don't know what is there in the header file. Also, if in spite of including the header file, you also need to provide the forward declaration, then it implies that the header is implemented incorrectly. I suspect that there is a circular dependency:
Make sure that no two header files include each other. For example, if
A.h
includesB.h
, thenB.h
must not includeA.h
, directly or indirectly.Use forward declaration and pointer-declaration to break such circular dependency. The logic is pretty much straight-forward. If you cannot include
A.h
inB.h
, which implies you cannot declareA a
inB.h
(because for this, you have to include the headerA.h
also). So even though you cannot declareA a
, you can still declareA *pA
, and for this a forward declaration ofA
is enough. That way you break the circular dependency.Hope that helps.