Mutual include in C++ .. how does it work?

12,370

Solution 1

Simple: don't let A.h include B.h. And vice-versa.

In general, header files should include as little as absolutely possible. You can use forward declaration to get around a lot of includes. The only time you absolutely must include something in a header is if there are objects that are used as non-references in that header.

So avoid doing that. Use Pimpl to avoid putting class members into headers. And unless it's template code or you need the inlining support, don't write the actual code in the headers.

The worst case is that you'll need to create a C.h that defines what A.h and B.h need.

Solution 2

Use Include guards in your header files. http://en.wikipedia.org/wiki/Include_guard

#ifndef MYHEADER_H
#define MYHEADER_H

//add decls here 

#endif

This way if your header files are included more than once the compiler ignores them.

Also as a rule of thumb if you are including B.h which has A.h , it would be better to include A.h and B.h in your application instead of relying on the include of B.h.

Also only put declarations in header file .

Avoid Definitions at all costs in header files.

Solution 3

You didn't say what those mutual dependencies are, so these are just guesses. In all of these I assume that A.h defines class A and B.h defined class B.

Case 1: Mutual dependency is through pointers or references.
For example, class A contains a data member of type B* and vice versa. In this case neither header needs to #include the other. Use a forward declaration instead.

Case 2: Mutual dependency is through objects.
For example, class A contains a data member of type B and vice versa. In this case you are hosed.

Case 3: Mixed dependencies.
For example, class A contains a data member of type B but class B contains a data member of type A*. Now A.h does need to #include B.h, but B.h merely needs a forward declaration of class A.

You should always use some kind of one-time include guard to prevent a header from being included multiple times.

Solution 4

Assuming that in each header you have a class, you can do like this:

Header file: "A.h"

#ifndef A_H
#define A_H
Class B;

Class A {
public:
  B name_of_B_;
}

#endif

With #ifndef A_H #define A_H #endif you ensure that each header is included only once. You should use this in pretty much every header file you produce, not only in this special case of double inclusion. With Class B; you declare that somewhere a class named "B" will be defined.

Class B {
public:
  A name_of_A_;
}

#endif

Same story as for class "B". In this way you avoid the infinite loop inclusion.

Share:
12,370

Related videos on Youtube

ArniBoy
Author by

ArniBoy

Updated on June 04, 2022

Comments

  • ArniBoy
    ArniBoy almost 2 years

    Possible Duplicate:
    Proper way to #include when there is a circular dependency?

    I am pretty new to C++ and have the question asked in the title. Or more precisely: If A.h includes B.h and B.h includes A.h, I get an error message because "include# file "C:...\A.h" includes itself". File: B.h

    I couldn't find a way to work around this, and my general setup pretty much requires that relation between those classes. Any possibility to make this work?

  • Enzo
    Enzo almost 13 years
    Thanks @Nicol, that's a good point. In general (not in this specific case of double inclusion), can you please explain why would you prefer a forward declaration to a normal inclusion?
  • ForceMagic
    ForceMagic over 11 years
    The includes present at the end of each header file are completely useless. Forward declaration such as Class A; is a mechanism to tell the compiler that a Class A will be present later on, same for Class B. At this point, it doesn't matter when either of Class A or B will be resolved, because you just told the compiler that they will both be there at the end of the compilation by using the forward declaration. Thus, the includes at the end of the header file can be removed because they serve no purpose. Regards ;)
  • Enzo
    Enzo over 11 years
    Right! Thanks for pointing it out.