1

Please find here below a simple example. I know that a .hpp file has to include or forward declare everything it uses I wonder if it is best practice to include all .hpp files that are used in the .cpp file as well. I am asking this because I recently saw on a new project I am working on, that people tend to avoid including headers in a lot of cases.

In this case: is it good to include b.hpp in a.cpp? I know it has already been included by including a.hpp, but I personally feel that if a symbol appears in a .cpp, it should be included (or forward declared if possible)

a.hpp

#pragma once
#include "b.hpp"

class C; //forward declaration of C

class A
{
public:
    B get_b();
private:
    B  _b;
    C* _c;
};

a.cpp

#include "a.hpp"
//needed or I can leave it out, since B is included already in a.hpp?
#include "b.hpp"

B A::get_b()
{
    return _b;
}
dau_sama
  • 4,247
  • 2
  • 23
  • 30
  • If you know it's included and that's never going to change, leave it out. If you're not sure, include it. There aren't any right answers here. – mah Nov 14 '13 at 20:55
  • that's the point, on a big code base, how can anyone be sure of what will change overtime? I personally try to be the most explicit possible. It's not the case in the project I've been recently assigned, and I'm wondering if adding includes all over the place (and replacing useless ones with forward declarations) – dau_sama Nov 14 '13 at 20:58
  • Personally, when working on large projects I sometimes prefer to have a single header file that includes anything my sources will need, and each source includes this. If you make a lot of changes to this single header it can make for some long build times, but once the header (meta-header, if you will) is stable, it's convenient. – mah Nov 14 '13 at 21:05
  • @mah - reducing header file inclusions can decrease compile time by orders of magnitude. As projects grow, the overhead of unneded header files can grow expodentially. Including "the world" is not a best practice – Glenn Teitelbaum Nov 14 '13 at 21:08
  • @GlennTeitelbaum that all depends on your environment. As I commented on your answer, _if_ you have support for precompiled headers, not only does overhead not grow, but it decreases. – mah Nov 14 '13 at 21:09

2 Answers2

3

Try to move #includes to .cpp files how much you can. It reduces compilation time and avoids propagating declarations along whole project. So, if you can just include b.hpp in the .cpp file.

Once you include b.hpp in the header file, you don't need to include it in the .cpp file. Including it again in the .cpp file has no effect due to header guards (if you put them).

masoud
  • 55,379
  • 16
  • 141
  • 208
1

There are two main concerns with regards to which files to include in a .cpp (and .hpp)

1) Compile time: Reducing the number of includes to reduce compile time

Roughly: Only include files that contain class data/function members or inline functions/templates that you use. If you only reference a class, a forward declaration is going to compile much faster than the whole include file.

2) Fragility: Not depending on an include file including something you need

If a.hpp includes b.hpp and you need somthing defined in b.hpp (see above) and then the implementor of a.hpp stops requiring a.hpp, your code will break

All of this is deterministic and effort should be put in to get it right

Glenn Teitelbaum
  • 10,108
  • 3
  • 36
  • 80
  • If you have a build environment that supports precompiled header files, the compile time issue goes away (and in fact is improved rather than degraded). – mah Nov 14 '13 at 21:08
  • @mah it becomes a question of scale - I'm not convinced it goes away - it is simply tolerable at lower scale. There are several posts about this: http://stackoverflow.com/questions/10577793/how-should-i-detect-bottleneck-of-compile-time-in-a-large-c-project – Glenn Teitelbaum Nov 14 '13 at 21:18
  • Glenn I know all of that. Header files should be agnostic, and you should be able to include them alone. I am focusing more on .cpp files, should I include everything it's used on a .cpp file as well? – dau_sama Nov 14 '13 at 21:19
  • @GlennTeitelbaum the whole purpose of a precompiled header file is that the header (and whatever it #includes) has been parsed by the compiler in advance -- this it's not just at a "lower scale", it's doing the work once rather than once per source file. – mah Nov 14 '13 at 21:20
  • @dau_sama This is talking about including files in a .cpp -- only if you must -- minor edit to help clarify this – Glenn Teitelbaum Nov 14 '13 at 21:27
  • for sake of clarity, in my example you advise not to include "b.hpp"in a.cpp file? – dau_sama Nov 14 '13 at 21:39
  • @dau_sama - you require it in a.hpp since you have a return by value and datamember of type B. You need it in a.cpp since you use B there. If somebody optimizes a.hpp by using references, etc. then a.cpp will still have it. This is admittedly an edge case since you would likely control and edit both in sync, but I still think its best practice. – Glenn Teitelbaum Nov 14 '13 at 21:46