Reputation: 2711
Suppose I have a file X.h which defines a class X, whose methods are implemented in X.cc. The file X.h includes a file Y.h because it needs Y to define class X. In X.cc, we can refer to Y because X.h has already included Y.h. Should I still include Y.h in X.cc ?
I understand that I don't need to and I can depend on header guards to prevent multiple inclusions. But on the one hand, including Y.h makes X.cc a little more independent of X.h (can't be completely independent of course). What is the accepted practice?
Another example: including <iostream>
in both .h and .cc files. I see some people do this
and some don't.
Upvotes: 10
Views: 5006
Reputation: 9232
It doesn't really matter very much [at least, not unless you have a gigantic project], but I would probably lean towards including it.
Upvotes: 1
Reputation: 504293
Be minimal. In headers, prefer forward declarations to full definitions. Use iosfwd
instead of ostream
, for example.
That said, X.h and X.cc represent the same logical unit. If your dependency on Y.h ever changed (for example, turned it into a forward declaration), you'd be changing the class anyway. So you can move #include "Y.h"
to X.cc justifiably.
In other words, X.cc and X.h go hand in hand. X.cc can reliably assume what's in X.h. So there's no need to re-include something if X.h does.
Dependencies where you 'include it anyway' occur with resources other than your own. For example, if you needed Z.h, you'd include it even if Y.h does. X.h does not get to reliably assume the contents of Y.h because X.h doesn't go with Y.h, it uses it.
Upvotes: 11
Reputation: 101496
#include
statements in header files can increase compilation times. For toy applications or large systems with only one dependency like you describe this won't be a problem. But as your application grows, so will compilation times. One resolution under MSVC is to use precompiled headers (which bring their own set of headaches), or to eliminate all #include
statements in headers. The latter is my default approach, and I try first to use forward declarations where needed:
class Y {public: int foo_; };
class Y;
class X { public: Y* y_; };
#include "y.h"
#include "x.h"
int main()
{
X x;
return 0;
}
If using forward declares isn't possible, just remember that #include
does nothing more than bring the contents of the specified file to that point, and this can be done just as easily from the cc file as from the header:
class Y {public: int foo_; };
class X {public: Y y_; }; // note this declaration requires a concrete type for Y
#include "y.h"
#include "x.h"
int main()
{
X x;
return 0;
}
Upvotes: 0
Reputation: 3986
I'm not sure why doing so would be a good practice.
On the other hand, not including unnecessary files in X.h
is something I consider to be a very good practice.
For example, in the following scenario:
#include "Y.h"
class X
{
private:
Y * m_pY;
public:
X();
~X();
}
It would be sufficient to forward declare Y
. Clients of class X
need not incur the expense of including the header file for Y
:
class Y; // include Y.h in X.cc instead
class X
{
private:
Y * m_pY;
public:
X();
~X();
}
This is possible in the header file, because the declaration of class X
doesn't require specific details about Y
(e.g. the size of an instance); only that Y
is a class. Further, clients of class X
never deal with the type Y
, since it's not part of X
's public interface.
For large projects, avoiding unnecessary include directives in header files can significantly improve build times.
It can also avoid polluting the namespace of users of your class with symbols from your private/implementation classes.
Upvotes: 3
Reputation: 39404
From your example I would only include X.h in X.cc only to reduce the number of includes. Yes, in the more general case where you have A.cc including X.h, and as a side effect being able to reference stuff in Y.h, when you can remove X.h you find yourself having to manually add Y.h because you didn't add it before. At least the compiler will be on your case and remind you.
In the case of <iostream>
you need it when you need it, whether in a header file or a module.
Upvotes: 0
Reputation: 1117
I would suggest including the header include for Y in X.cc even if it seems redundant. It gives you the advantage of being very explicit as to your dependencies.
As a related note, you should always #include the associated header for a cpp file as the first #include'd file. (The first include in X.cpp should be X.h) This guarantees that the header include the proper files to resolve its own dependencies, otherwise you could inadvertently be relying on the ordering of includes in your source file.
Upvotes: 6
Reputation: 3662
I think you should. As your code grows and some implementation changes, some includes my be removed from a header file that is included by another header file that is included in some header file... It might get real nasty to find out why something that has nothing to do with changes you (or someone else) made isn't working anymore.
Upvotes: 1