2

My header files look like:

// A.hpp --- A's interface

#ifndef MY_H
#define MY_H

#include<string>
#include<vector>

class A {
 public:
  A(const std::string& name);
  std::vector<double> foo() const;
 private:
  std::string m_name;
};

#endif

And my implementation files look like:

// A.cpp --- A's interface implementation
#include<A.hpp>

#include<implementation_detail.hpp>

A::A(const std::string& name)
 : m_name(name) { }

std::vector<double> A::foo() const {
 std::vector<double> r;
 r.push_back(1);
 return r;
}

My stand is that I do not #include string or vector in the implementation file because they are already declared in the interface, and #includeing them in the implementation file is superfluous at best, and detrimental at worse**.

Of course, A's implementation will #include all implementation details not visible from the interface.

My questions: Am I correct? Can this practice affect my code negatively?

** It is far-fetched, but the number of includes (and the include guards used) can have an effect in compilation speed for very large projects; this article is interesting.

Escualo
  • 40,844
  • 23
  • 87
  • 135
  • `#include`ing extra doesn't hurt if you are using the library, but not doing so creates extra dependencies that might cause issues if you refactor. This is one reason it's a good idea to `#ifdef` your headers in any project of significant size. – abiessu Oct 31 '13 at 22:26
  • @abiessu can you expand? I'm not sure I see how *not doing so creates extra dependencies that might create issues if [I] refactor*. – Escualo Oct 31 '13 at 22:52
  • The answers below cover what I intended to say better than I know how to, but basically if you are depending on a header file to `#include` files that will be used in a source file, then you have a dependency. – abiessu Oct 31 '13 at 23:11

4 Answers4

2

It's a matter of style and personal preference.

For header files, my personal preference is to make the header file stand on its own, but just barely. By "stand on its own" I mean that I should be able to #include that header in some random source file and that source file will still compile.

#include "some_random_header_file.h"
int main () {}

The above should always compile. By "just barely", I mean that the header should be free of gratuitous #include directives. If some #include does not provide functionality used directly in a header file, I don't #include that other header in the header file.

For source files, my personal preference is to #include every header that provides functionality used in the source file. If the code a source file calls std::string::append, that source file had better #include <string> -- even if some other header has already included it.

David Hammen
  • 32,454
  • 9
  • 60
  • 108
  • 1
    I never thought of adding that as a *self-containment test* for my header files; it is very simple, and seems powerful. Thanks! – Escualo Oct 31 '13 at 22:49
  • In my example, would you have included both `string` and `vector` in the implementation file? – Escualo Oct 31 '13 at 23:14
  • @Arrieta - Yes. That is exactly what I would do. Both are needed in the header because your header won't compile without them, and both provide functionality that is directly used in the implementation (so I would also include them in the implementation file). That is my personal preference. Other people, and other organizations, have other rules. – David Hammen Oct 31 '13 at 23:25
  • I would also include them in the header (as presented). I would just not include them **also** in the implementation. From what I understand you would include them in both. – Escualo Oct 31 '13 at 23:42
  • @Arrieta he might be `using ` them in to context. Another include would be superfluous. – Captain Giraffe Nov 01 '13 at 00:02
1

You are correct. The cpp file is the compilation unit. That is where the headers are used. Everything included by those headers is also effectively in the cpp file.

Worth noting is that:

  • Do not include stuff you need in the cpp file in the header.
  • Be explicit in your types in the header. I.e. use std::string as the type not using std::string or even worse using namespace std; in the header.
  • It is fine to use using statements as is convenient in the cpp file.

You do not want to introduce more types than necessary to the people including your headers.

Captain Giraffe
  • 14,407
  • 6
  • 39
  • 67
0

It's a matter of style, not correctness.

However, it is considered a good style to only include things that are absolutely needed. So if your interface needs these headers, then your .h has to include them.

At the same time, it is considered a good style to make each header self-sufficient - that is, in order to use it's facilities it should be sufficient to include it without including anything else.

So, given these two points, you are right to have those #include directives in your header.

Alexander L. Belikoff
  • 5,698
  • 1
  • 25
  • 31
  • I'm not sure I understand your answer. I **do** include everything (self-contained and all) in the interface (header) files. My point is that I do not *also* include them in the **implementation* (the `.cpp`). Is this what you meant? – Escualo Oct 31 '13 at 22:30
  • That's one of the points. Since you already include them in the header, there is no need to include them again. – Alexander L. Belikoff Oct 31 '13 at 22:37
0

If you're really concerned about #include performance, you have some options here:

vines
  • 5,160
  • 1
  • 27
  • 49
  • Thanks. It was not so much about the performance (which I try to keep in mind), but more about a dark (or not so) case in which choosing not to include them in the implementation could cause an error or other kind of inconvenience in my code. – Escualo Oct 31 '13 at 22:51