I have seen many explanations on when to use forward declarations over including header files, but few of them go into why it is important to do so. Some of the reasons I have seen include the following:
Coming from a .net background I find header management frustrating. I have this feeling I need to master forward declarations, but I have been scrapping by on includes so far.
Why cannot the compiler work for me and figure out my dependencies using one mechanism (includes)?
How do forward declarations speed up compilations since at some point the object referenced will need to be compiled?
I can buy the argument for reduced complexity, but what would a practical example of this be?
To have such a header file is poor practice and bad design. The problem is that it will create a tight coupling dependency between every single file of your project, even if they are completely unrelated. Good program design is to create autonomous modules that only include the resources they are using.
Generally, you only want to put the minimum necessary includes into a class header file, as anyone else who uses that header will be forced to #include all of them too.
The need for header files results from the limitations that the compiler has for knowing about the type information for functions and or variables in other modules. The compiled program or library does not include the type information required by the compiler to bind to any objects defined in other compilation units.
using declaration (the most common being using namespace std; ) should not appear in a header file because they pollute the namespace of the source file in which it is included.
"to master forward declarations" is not a requirement, it's a useful guideline where possible.
When a header is included, and it pulls in more headers, and yet more, the compiler has to do a lot of work processing a single translation module.
You can see how much, for example, with gcc -E
:
A single #include <iostream>
gives my g++ 4.5.2 additional 18,560 lines of code to process.
A #include <boost/asio.hpp>
adds another 74,906 lines.
A #include <boost/spirit/include/qi.hpp>
adds 154,024 lines, that's over 5 MB of code.
This adds up, especially if carelessly included in some file that's included in every file of your project.
Sometimes going over old code and pruning unnecessary includes improves the compilation dramatically just because of that. Replacing includes with forward declarations in the translation modules where only references or pointers to some class are used, improves this even further.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With