Reputation: 575
I understand if a.h
includes b.h
and I don't declare anything from b.h
in my header including only a.h
is good practice. If I were to declare anything from b.h
in my header then I should include both a.h
and b.h
to make my header self-sufficient.
In my header I do declare both class A
from a.h
and class B
from b.h
. However, class A
depends on class B
, so I always use them together. I never use class B
independently of class A
. In this case does it still make sense to include both a.h
and b.h
?
a.h
#include "b.h"
#include <queue>
class A
{
private:
std::queue<B> mFoo;
}
In my actual code I think it makes my intention clearer when I include just my event system for example and not a number of includes that seem superfluous to me.
Upvotes: 0
Views: 179
Reputation: 5055
You should always include direct dependencies: if a depends directly on b and c, even if b already includes c, a should include both.
Be explicit about your dependencies. You should not rely on the fact that some other module already depends on the module you'd have to include. You never know how the dependency tree will change in the future.
In this regard, having implicit dependencies makes your code fragile.
To make sure you don't redefine something by including it twice, you can put header guard inside your header files:
#ifndef GRANDFATHER_H
#define GRANDFATHER_H
struct foo {
int member;
};
#endif /* GRANDFATHER_H */
You could also use
#pragma once
But not every compiler supports it.
That way even if the preprocessor will step on same include more than once, It won't re-include the code.
Upvotes: 1
Reputation: 33106
My rule: Given some random header foo.h
, the following should compile clean, and preferably should link and run as well:
#include "foo.h"
int main () {}
Suppose foo.h
doesn't contain any syntax errors (i.e., a source file that includes it in the context you intended compiles clean) but the above nonetheless doesn't compile. This almost always means there are some missing #include
directives in foo.h
.
What this doesn't tell you is whether all of the headers included in foo.h
truly are needed. I have a handy little script that checks the above. If it passes, it creates a copy of foo.h
and progressively comments out #include
directives and sees if those modified versions of foo.h
pass the above test. Any that do pass are indicative of suspect superfluous #include
directives.
The problem is that the #include
directives deemed to be superfluous might not be superfluous. Suppose foo.h
defines class Foo
, which has data members of type Bar
and Baz
(not pointers, members). The header foo.h
correctly includes both bar.h
and baz.h
because that is where those two classes are defined. Suppose bar.h
happens to include baz.h
. As the author of foo.h
, I don't care. I should still include both of those headers in foo.h
because foo.h
has direct dependencies on both of those other headers. My script will complain about suspect superfluous headers in this case. Those complaints are hints, not mandates.
On the other hand, fixing foo.h
so that my simple test program above compiles clean is a mandate.
Upvotes: 0