7

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?

Community
  • 1
  • 1
ArniBoy
  • 127
  • 1
  • 1
  • 3
  • Good question. Preprocessors work line by line, you would study how `#ifdef`, `#define`, and `#endif` work :-) – Stan Jul 22 '11 at 13:39

7 Answers7

7

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.

xeon111
  • 1,025
  • 9
  • 20
6

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.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • 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? – Enzo Jul 22 '11 at 14:04
2

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.

David Hammen
  • 32,454
  • 9
  • 60
  • 108
1

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.

Enzo
  • 964
  • 1
  • 9
  • 20
  • 1
    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 ;) – ForceMagic Oct 11 '12 at 00:22
0

You have a Circular Dependency. It can be solved using Include Guards.

overcoder
  • 1,523
  • 14
  • 24
0

Try adding header guards,

#ifndef _A_H_
#define _A_H_
...
..
.
#endif /* #ifndef _A_H_ */

You should never include a header file twice, results in redefinition..

bluefalcon
  • 4,225
  • 1
  • 32
  • 41
0

When a header file is added to a file it gets included during the preprocessing part of compilation. So including B.h into A.h. And including A.h in B.h. It is kind of infinitely recursive and the file gets included multiple times.

Including B.h in A.h amounts to A.h <- B.h Including A.h in B.h amounts to Bh <- A.h

So its king of infinite recursive loop.

Akash Gangil
  • 141
  • 1
  • 3
  • 9