Question

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.

Was it helpful?

Solution

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.

OTHER TIPS

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.

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.

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

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top