- Is there some preferred way to organize ones include directives?
- Is it better to include the files you need in the
.cpp
file instead of the.h
file? Are the translation units affected somehow? - How about if I need it in both the
.h
file and.cpp
file, should I just include it in the.h
file? Will it matter? - Is it a good practice to keep the already defined files in a precompiled header (
stdafx.h
), for instance std and third party libraries? How about my own files, should I include them in astdafx.h
file along the way as I create them?
// myClass.h
#include <string>
// ^-------- should I include it here? --------
class myClass{
myClass();
~myClass();
int calculation()
};
// myClass.cpp
#include "myClass.h"
#include <string>
// ^-------- or maybe here? --------
[..]
int myClass::calculation(){
std::string someString = "Hello开发者_运维技巧 World";
return someString.length();
}
// stdafx.h
#include <string.h>
// ^--------- or perhaps here, and then include stdafx.h everywhere? -------
- You should have them at the top of the file, all in one place. This is what everyone expects. Also, it is useful to have them grouped, e.g. first all standard headers, then 3rd-party headers (grouped by library), then your own headers. Keep this order consistent throughout the project. It makes it easier to understand dependencies. As @James Kanze points out, it is also useful to put the header that declares the content first. This way you make sure that it works if included first (meaning it does no depend on any includes that it does not include itself).
- Keep the scope as small as possible, so that a change in the header affects the least number of translation-units. This means, whenever possible include it in the
cpp
-file only. As @Pedro d'Aquino commented, you can reduce the number of includes in a header by using forward declarations whenever possible (basically whenever you only use references or pointers to a given type). - Both - explicit is better than implicit.
- After some reading, I believe you should only include headers in the PCH if you are confident that they do not change anymore. This goes for all standard headers as well as (probably) third party libraries. For your own libraries, you be the judge.
This article on Header file include patterns should be helpful for you.
- Is there some preferred way to organize ones include directives?
Yes, you can find them in the above article.
- Is it better to include the files you need in the .cpp file instead of the .h file? Are the translation units affected somehow?
Yes, it is better to have them in .cpp. Even, if a defined type is required in definition of another type, you can use forward declaration.
- How about if I need it in both the .h file and .cpp file, should I just include it in the .h file? Will it matter?
Only in .h file, but it is suggested to forward declare in header files, and include in .cpp files.
- Is it a good practice to keep the already defined files in a precompiled header (stdafx.h), for instance std and third party libraries? How about my own files, should I include them in a stdafx.h file along the way as I create them?
I personally have not used precompiled headers, but there has been a discussion on them on Stackoverflow earlier:
Precompiled Headers? Do we really need them
Is there some preferred way to organize ones include directives?
No common conventions. Some suggest alphabet-sorting them, I personally dislike it and prefer keeping them logically grouped.
Is it better to include the files you need in the .cpp file instead of the .h file?
In general, yes. It reduces the count of times that the compiler needs to open and read the header file just to see the include guards there. That may reduce overall compilation time. Sometimes it's also recommended to forward-declare as much classes as possible in the headers and actually include them only in .cpp's, for the same reason. The "Qt people" do so, for example.
Are the translation units affected somehow?
In semantic sense, no.
How about if I need it in both the .h file and .cpp file, should I just include it in the .h file? Will it matter?
Just include it in the header.
Is it a good practice to keep the already defined files in a precompiled header (stdafx.h), for instance std and third party libraries? How about my own files, should I include them in a stdafx.h file along the way as I create them?
Precompiled headers can significantly reduce compilation times. For example: one of my projects that includes boost::spirit::qi
compiles in 20 secs with PCH on, and 80 secs — without. In general, if you use some heavily template-stuffed library like boost
, you'd want to utilise the advantage of PCH.
As for the question in your code sample: since you don't use std::string in the header, it's better to include it in the .cpp
file. It's alright to #include <string>
in stdafx.h
too — but that will just add a little bit of complexity to your project and you'll hardly notice any compilation speed-up.
(4) I wouldn't recommend to include any additional files into stdafx.h. or similar "include_first.h" files. Direct including into cpp or particular h files allow you to express dependencies of your code explicitly and exclude redundant dependencies. It is especialy helpful when you decide to decompose monolithic code into a few libs or dll's. Personally, I use files like "include_first.h" (stdafx.h) for configuration purpose only (this file contains only macro definitions for current application configuration).
It is possible to provide precompiled headers for your own files by marking another file to stop precompilation instead of stdafx.h (for instance, you can use special empty file named like "stop_pch.h").
Note, precompiled headers may not work properly for some kinds of sofisticated usage of the preprocessor (particulary, for some technics used in BOOST_PP_* )
From the performance point of view:
Changing any of the headers included from stdafx.h will trigger a new precompilation, so it depends on how "frozen" the code is. External libraries are typical candidates for stdafx.h inclusion, but you can certainly include your own libraries as well - it's a tradeoff based on how often you expect to change them.
Also, with the Microsoft compiler you can put this at the top of each header file:
#pragma once
This allows the compiler to fully skip that file after the first occurrence, saving I/O operations. The traditional ifndef/define/endif pattern requires opening and parsing the file every time it's included, which of course takes some time. It can certainly accumulate and get noticeable!
(Make sure to leave the traditional guards in there, for portability.)
It might be important to notice that the order of classes in Translation Unit need to be correct or some c++ features are just disabled and results in a compile-time error.
Edit: Adding examples:
class A { };
class B { A a; }; // order of classes need to be correct
精彩评论