One thing i do know for sure. When one creates a CPP file,
one needs to include the H file. Now, having said that, i
wonder if there are some general hints, requirements or
standard guide lines on what and how to include.
Suppose that we have a project consisting of a number of
classes and structs. Some of them using the others, some
using all of them. What is a good approach when including?
A few rules I believe are worth sticking to with headers:
1. When you have classes and structs that know about other classes and
structs, use forward declarations whenever you can to reduce the
number of headers included in other headers. See
http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.11
and the ones that follow it. Although that FAQ talks about resolving a
circular dependency, it describes the general principle of forward
declarations and how they are used.
2. The point above will hopefully reduce the number of includes you
need within a particular header. However, *always* make sure that a
header *does* include everything it needs to be a stand-alond
compileable unit. A source file that contains nothing except #include
"my_header.h" should compile with no errors. Example (untested but I
think simple enough to make the point):
// my_header.h original
struct person
{
std::string name;
};
// test_my_header.cpp original
#include "my_header.cpp"
test_my_header.cpp will not compile. You will get an error because the
compiler does not know what std::string is. One solution is to change
test_my_header.cpp:
// test_my_header.cpp modified in an un-good way
#include <string>
#include "my_header.cpp"
Now it compiles. But if you follow this approach, you force yourself
and everybody else who ever uses my_header.h to have to remember to
include <string> before my_header.h *every time* they use it. Much
better is to modify my_header.h
// my_header.h modified in a good way
#include <string>
struct person
{
std::string name;
};
Now the original version of test_my_header.cpp will compile cleanyl,
and users of your header can simply include it without needing to jump
through any other hoops.
3. Always use include guards in every header. Doesn't seem to be a FAQ
on that, but wikipedia will suffice
http://en.wikipedia.org/wiki/Include_guard.
No, my example above does not follow this advice. That was for clarity
in making the point. In the real world I would certainly put an
include guard in my_header.h.
4. Don't put using directives or using declarations in headers (at
least not at global scope - they can be necessary inside class
definitions). Using directives and declarations have pros and cons and
whether to use them or not needs to be judged on a case by case basis.
If you put one in a header, you force its use on everyone who ever
includes that header, whether they want it or not. Don't do that - let
them decide for themselves.
HTH
Gavin Deane