In my C++ project when do I have to use inclusion (#include \"myclass.h\"
) of header files? And when do I have to use forward declaration of the class (cl
As a rule try the forward declaration first. This will reduce compile times etc. If that doesn't compile go for the #include
. You have to go for the #include if you need to do any of the following:
new
/delete
, copy etc.(6,7,8,9 from @Mooing Duck)
They're are probably more but I haven't got my language law hat on today.
As a beginner, you should always #include header files when you need to use the types or functions they contain - do not try to "optimise" your build by forward declaring things - this is hardly ever necessary, even on large projects, provided the project is well architected.
The only time you absolutely need a forward declaration is in situations like this:
struct A {
void f( B b );
};
struct B {
void f( A a );
};
where each struct (or class) refers to the type of the other. In this case, you need a forward declaration of B to resolve the issue:
struct B; // forward declaration
struct A {
void f( B b );
};
struct B {
void f( A a );
};
There are several problems to forward declaration:
Forward declarations are difficult for others to maintain. For instance, if a header file contains:
include "MyProject/MyWidgets/MyFooWidgets/FooUtil/Foo.h"
rather than the forward declaration
class Foo ;
it is easy for others to find where the class Foo is declared. With forward declaration, it is not that obvious; some IDEs like Eclipse may open the forward declaration when the user tries to open the declaration of a variable.
"Could not find file MyProject/MyWidgets/MyFooWidgets/FooUtil/Foo.h"
since then you will know where to look for the corresponding Foo.cpp
and identify the library that contains it.If you think your build is taking too long, then try doing a compile only with no link. If your code takes 10 seconds to compile and 10 minutes to link, the problem has nothing to do with a few extra includes. Similarly, if your header file contains so much stuff in it that it is actually causing a performance problem then it is probably time for you to refactor the content of that file into multiple smaller header files.
So when is it OK to forward declare? If you do it in the same header file as the real declaration.
Example:
class Foo ;
typedef Foo* FooPtr ;
typedef Foo& FooRef ;
class Foo
{
public:
Foo( ) ;
~Foo( ) ;
}
OR
class TreeNode ;
class Tree
{
private:
TreeNode m_root ;
}
class TreeNode
{
void* m_data ;
} ;
If you only need a pointer to the class and you don't need any knowledge about the class rather than its name, you can use the forward declaration.
You should strive towards minimizing your #include
s both in order to reduce compilation times but also to help with modularity and testability. As @ypnos says, class forwards are excellent when you only need pointers.
For some practical tips on how to reduce header dependencies, see e.g. this article.