Why shouldn't I put my #include statements in .h file?

Viewed 606

I have been placing my #include statements in the header file, then only including the header in main to make my main file look cleaner. However, every other C++ code I look at leaves them in main. Does it make a difference either way? If it does, why? Example:

Header:

#pragma once
#include <iostream>
#include <string>
#include <iomanip>
#include <fstream>
using namespace std;

class Question
{
private:

Main:

#include "Header.h"

int main()
{
3 Answers

There are a few considerations:

  1. you want to minimize header inclusions because they slow down the builds, and increase the dependency tree. Code that includes your header depends on every header it includes, and every header that they include, and so on, all the way down. Suppose a some user includes your header, and you include 20 other headers in it, then

    • any time any of those headers you include changes, the client code has to recompile
    • client code has to parse all those headers every time it builds.

    The real problem is the multiplying effect: you get slower builds that also have to be done more often (because the number of files depended on goes up.) This is partly why c++ projects are so slow to build. Some headers contain substantial amounts of complex template code, and it gets compiled over and over, for each translation unit that it appears.

  2. The fewer inclusions your headers have, the less implementation detail you depend on as well. The attitude of "put lots of code into headers!" tends to make them contain more implementation detail than necessary. That is, instead of merely declaring a function, it also defines the function, then that means development work happens in the header, not the cpp file. So that makes the headers change even more often, causing everyone who includes it to need to be rebuilt for (oftentimes) no good reason.

  3. When you keep an include isolated inside a .cpp file, then only that cpp file has the dependency on it--not your users. This helps isolate your clients from having to parse and build the headers that you use but don't need to provide.

  4. More things included in headers also causes more names to be visible to consumer code. This can increase name collisions, create ambiguities, possibly have macros interfere, and so on. Namespaces can help, but if a user gets 100 overloads of operator<< because they include your header, then every time they need to resolve an overloaded <<, the compiler has 100x more functions to choose from to decide which one to call, which again can slow down the build. And so on.

The goal is to minimize what you expose to your users, and the header is what you expose.

Only put the minimum required #include in a .h file. That way you prevent unexpected code collisions and unnecessary make dependencies.

It only makes a difference for bigger projects. If you include a lot of headers in headers and have a lot of source files you will include headers multiple times. This can drastically increase compile times.

For small projects (~10000 lines) it is fine either way.

Related