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 ofAat the site of variable declaration. All it needs to know thatAis 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 usually4bytes on 32bit system or8bytes 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 typeAat 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
Ain the headerB.h, then you have to include the header fileA.hin the implementation file ofBwhich isB.cpp, because in the implementation file ofB, you need to access the members ofAfor 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.hincludesB.h, thenB.hmust 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.hinB.h, which implies you cannot declareA ainB.h(because for this, you have to include the headerA.halso). So even though you cannot declareA a, you can still declareA *pA, and for this a forward declaration ofAis enough. That way you break the circular dependency.Hope that helps.