Cricketer
Cricketer

Reputation: 2431

Where should I put C++ #include's? In the header or in the implementation?

Suppose I have a class called CameraVision in the file CameraVision.cpp.

The constructor for this class takes in a vector of IplImage* (IplImage is a C struct that represents an image in OpenCV). I need to #include opencv.h either in CameraVision.hpp or CameraVision.cpp.

Which is better and why? (#including these in CameraVision.hpp or in CameraVision.cpp?)

Also, where should I #include STL <vector>, <iostream>, etc. ?

Suppose the client of CameraVision.cpp also uses <vector> and <iostream>. The client would obviously #include CameraVision.hpp (since he is a client of CameraVision). Should the client of CameraVision.cpp also #include , <iostream>, etc. if they have already been #include'd in CameraVision.hpp? How would the client know this?

Upvotes: 3

Views: 2377

Answers (4)

Coder909
Coder909

Reputation: 71

The convention that I use in writing C++ is to include headers in the *.hpp header file if those headers are required to be there for the compiler to resolve things. If you have the class IplImage in the *.hpp declaration, you can get away with adding forward declaration (https://en.cppreference.com/w/cpp/language/class), only if the members of IplImage are NOT referenced or mentioned in the *.hpp file. You would then add the include in the *.cpp file. This should reduce compiled times.

// The CameraVision.hpp file
#pragma once
class IplImage; // forward declaration
class CameraVision
{
public:
   CameraVision(std::vector<IplImage*> *pIplImageVec);
   ...
};

Then you should include the headers in the *.cpp implementation file that are required to be there for compilation, and that are NOT already defined in the *.hpp file. Do not depend on other headers already having those includes, since those dependencies can be changed in the future.

In summary:

  1. Add #includes in the header file if they are required to be there.
  2. If those #includes can be changed to forward declarations, then do so.
  3. Add the header #include to the implementation file (.cpp) and #include anything else that is not in the header, but that is needed by the .cpp file to compile, whilst not depending on any other headers including for you.

Upvotes: 0

DevSolar
DevSolar

Reputation: 70381

The rule here is: Limit scope. If you can get away with having the include in the implementation file only (e.g. by using a forward declaration, including <iosfwd> etc.), then do so. In public interfaces, i.e. the headers that your clients will include to use a library of your making, consider using the PIMPL pattern to hide any implementation details.

The benefits:

1) Clarity of code. Basically, when somebody is looking at a header file, he is looking for some idea of what your class is about. Every header included adds "scope" to your header: Other headers to consider, more identifiers, more constructs. In really bad code, every header includes yet more headers, and you cannot really understand one class without understanding the whole library. Trying to keep such dependencies at a minimum makes it easier to understand the interface of a class in isolation. ("Don't bother what IplImage actually is, internally, or what it can do - at this point all we need is a pointer to it").

2) Compile times. Since the compiler has to do the same kind of lookup as described in 1), the more includes you have in header files, the longer it takes to compile your source. In the extreme, the compiler has to include all header files for every single translation unit. While the resulting compile time might be acceptable for a once-over compilation, it also means that it has to be re-done after any change to a header. In a tight edit - compile - test - edit cycle, this can quickly add up to unacceptable levels.

Edit: Not exactly on-topic, but while we're at it, please don't use using in header files, because it's the opposite of limiting scope...

Upvotes: 9

Alexander Mihailov
Alexander Mihailov

Reputation: 1152

To avoid extra includings, you should use #include in implementation (.cpp) files in all cases, except in situations when names that you are importing, used in prototypes or declarations, which your module exports.

For example:

foo.h:

#ifndef _FOOBAR_H_
#define _FOOBAR_H_

#include <vector>

void foo();
std::vector<int> bar();

#endif // _FOOBAR_H_

foo.cpp:

#include "foo.h"
#include <iostream>

void foo() {
    std::cout << "Foo";
}

std::vector<int> bar() {
    int b[3] = {1, 2, 3};
    return std::vector<int>(b, b+3);
}

Upvotes: 5

Verax
Verax

Reputation: 2519

If a type is used/referenced only within the implementation file, and not in the header file, you should #include only in the implementation file, upholding the principle of limited scope.

However, if your header file references a type, then your header file should #include that type's header file. The reason being that your header file should be able to be completely understood and have everything it needs when it is #included.

One justification for this perspective is not just for building/compiling, but also tooling. Your development environment may parse header files to provide you with type assistance (e.g. Intellisense, Command Completion, etc...) which may require complete type information to work properly.

Another justification is if your header file is used by another party, that that party has enough information about your types to make use of your code. And they should not have to #include several files to get one type to compile.

You should not #include a type's header file in another type's header file simply to avoid having to #include two files in the implementation file. Instead, a third header file should be made for the purpose of aggregating those types.

Upvotes: 5

Related Questions