0

I'm new to C++. I'm in a situation that I have multiple classes. And I just learned that I need to include the header file of that class in order to use it in my current class.

For example, I have 'main.cpp', 'object1.h', 'object2.h' and 'object3.h'.

I don't know if I should do this way: 'main.cpp' includes all three: 'object1.h', 'object2.h', 'object3.h' (centralized style)

or this way:

'main.cpp' include 'object1.h', 'object1.h' include 'object2.h', 'object2.h' include 'object3.h' (linear style)

And if I want to use object2 in my object3. I probably need to let 'object3.h' additionally include 'object2.h', right?

For this case, I wonder if the standard way is: 1. include the header file when you need to use it. 2. include all possible header file even you do not know if you will use it.

  • 2
    1. Every cpp must include every header with declarations which are needed in cpp. 2. The convention is not to rely on indirect dependencies although this would work. 3. The 2. may cause that headers are included multiple times - directly and indirectly. To prevent duplicated declarations, it's usual to use [include guards](https://en.wikipedia.org/wiki/Include_guard). – Scheff's Cat Aug 25 '19 at 07:37
  • Related : https://stackoverflow.com/questions/464560/how-to-use-include-directive-correctly – Gaurav Singh Aug 25 '19 at 07:46

4 Answers4

2

All headers should have guards.

If header A uses header B, it should include it.

If main.cpp directly uses a header, it should include it.

user31264
  • 6,557
  • 3
  • 26
  • 40
0

You should include headers in your .cpp files, and try to avoid headers including headers where possible because of (readability, compile time, etc), you want to include as little as needed.

  • Usually code should be first optimized for maintenance (aka readability), and second for runtime performance (if necessary). (Sometimes in opposite order if really necessary.) To optimize code for compile time is usually not an issue. It might be contrary to first and second which are much more important. – Scheff's Cat Aug 25 '19 at 07:40
0

Include only what you need from where you need it. E.g., if object1 is composed of, or inherits from, object2:

object1.h

#include "object2.h"
class object1 {
    object2 o2;
};

main.cpp

#include "object1.h"
int main() {
    object1 o1;
}

object2 might need object3 but since obect1 and main doesn't need it directly we don't need to include it in any of those files.


If object1 only uses object2 internally:

object1.h

// no composision of, or inheritance from, object2
class object1 {        
    void func();
};

object1.cpp

#include "object2.h"
void object1::func() {
    object2 o2;
    ...
}

main.cpp

#include "object1.h"
int main() {
    object1 o1;
}

Here object1 uses object2 in its .cpp file, so the .cpp file includes object2.h


And so on. In main.cpp you do exactly the same. Include the headers for the classes you instantiate directly.

Ted Lyngmo
  • 93,841
  • 5
  • 60
  • 108
0

The main purpose of headers is to reuse declarations instead of repeating declarations (aka code duplication) which would be error-prone.

Hence, every translation unit (aka cpp source) has to include all headers (with declarations) as needed.

A declaration in a header may depend on other declarations e.g. when a class is derived from another. In this case, the header should include all needed headers (instead of relying on that it is done in the right order in the cpp source where header itself is included).

The convention is, to include all headers with declarations in a header or cpp source which are used i.e. not relying on indirect dependencies.

This may cause, that headers are included multiple times in the same translation unit – directly and indirectly as well. Due to this, duplicated declarations may occur. To prevent this, include guards are used.

Another possible issue are cyclic dependencies: Header A includes header B. Header B includes header A. This ends up that one of these headers misses the declaration of the other → compiler errors. Such cyclic dependencies must be broken by forward declarations.

Scheff's Cat
  • 19,528
  • 6
  • 28
  • 56