@@ -1751,7 +1751,12 @@ else: dnl Check that the X11 header files don't use implicit declarations: ACMSGCHECKING(if X11 header files implicitly declare return values).
You should always include all headers defining any objects used in a.cpp file in that file regardless of what you know about what's in those files. You should have include guards in all header files to make sure that including headers multiple times does not matter. The reasons:.
This makes it clear to developers who read the source exactly what the source file in question requires. Here, someone looking at the first few lines in the file can see that you are dealing with Texture objects in this file. This avoids issues where refactored headers cause compilation issues when they no longer require particular headers themselves.
For instance, suppose you realize that RenderObject.hpp doesn't actually need Texture.hpp itself. A corollary is that you should never include a header in another header unless it is explicitly needed in that file. The general rule of thumb is: include what you use. If you use an object directly, then include its header file directly. If you use an object A that uses B but do not use B yourself, only include A.h.
Also while we are on the topic, you should only include other header files in your header file if you actually need it in the header. If you only need it in the.cpp, then only include it there: this is the difference between a public and private dependency, and will prevent users of your class from dragging in headers they don't really need. Opinions differ on this, but I am of the view that every file (whether c/cpp source file, or h/hpp header file) should be able to be compiled or analysed on its own. As such, all files should #include any and all header files that they need - you should not assume that one header file has already been included previously.
It is a real pain if you need to add a header file and find that it uses an item that is defined elsewhere, without directly including it. So you have to go find (and possibly end up with the wrong one!) On the other side, it doesn't (as a general rule) matter if you #include a file you don't need. As a point of personal style, I arrange #include files in alphabetical order, split into system and application - this helps reinforce the 'self contained and fully coherent' message. It depends on whether that transitive inclusion is by necessity (e.g. Base class) or because of an implementation detail (private member). To clarify, the transitive inclusion is necessary when removing it can only be done after first changing the interfaces declared in the intermediate header.
Since that's already a breaking change, any.cpp file using it has to be checked anyway. Example: A.h is included by B.h which is used by C.cpp. If B.h used A.h for some implementation detail, then C.cpp shouldn't assume that B.h will continue to do so. But if B.h uses A.h for a base class, then C.cpp may assume that B.h will continue to include the relevant headers for its base classes. You see here the actual advantage of NOT duplicating header inclusions. Say that the base class used by B.h really didn't belong in A.h and is refactored into B.h itself.
B.h is now a standalone header. If C.cpp redundantly included A.h, it now includes an unnecessary header. I am taking a similar slightly different approach from proposed answers. In headers, always include just a bare minimum, just what is needed to make the compilation pass.
Use forward declaration wherever possible. In the source files, it is not that important how much you include. My preferences are still to include minimum to make it pass. For small projects, including headers here and there will not make a difference. But for medium to large projects, it can become a problem. Even if the latest hardware is used to compile, the difference can be noticeable.
The reason is that the compiler still has to open the included header and parse it. So, to optimize the build, apply the above technique (include bare minimum, and use forward declare).
Although a bit outdated, (by John Lakos) explains all this in details. I have noticed optimization on some of the latest compilers to deal with this. They recognize a typical guard statement, and process it. Then, when #including it again, they can optimize out the file load completely. However, your recommendation of forward declarations is very wise to reduce the number of includes. Once you begin using forward declarations, it becomes a balance of compiler run-time (improved by forward declarations) and user-friendliness (improved by convenient extra #includes), which is a balance each company sets differently. – Nov 8 '14 at 5:16 1.
I had to -1 this because I honestly believe any sentence which is in the form of 'Good practice is not to worry about your strategy as long as it compiles' leads people to bad judgement. I have found that approach leads very rapidly towards unreadability, and unreadability is ALMOST as bad as 'doesn't work.' I have also found many major libraries which disagree with the results from both cases you describe.
As an example, Boost DOES do the 'collections' headers you recommend in case 2, but they also make a big deal out of providing class-by-class headers for when you need them. – Nov 8 '14 at 5:23 3.