Header files problem ... recursive includes

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • jefe
    New Member
    • May 2010
    • 3

    Header files problem ... recursive includes

    I have 8 header files in a cpp project, and some cross refer to each other:

    ie
    Code:
    #include "Observer.h" in file "Subject.h"
    
    
    #include "Subject.h" in file "Observer.h"
    and the compiler is getting into an infinite recursive loop with these includes.

    Is there any command options i can use to specify that a file should only be included once?

    Thanks
  • weaknessforcats
    Recognized Expert Expert
    • Mar 2007
    • 9214

    #2
    I recommend using an inclusion guard iin each of your hesder files:

    Code:
    #ifdef SUBJECTH
    #define SUBJECTH
    
    ...contents of subject.h gl here
    
    #endif
    The first time the file is included SUBJECTH is not defined. It is immediately defined followed by the contents of the header file.

    On subsequent includes, SUBJECTH is defined so the preprocessor skips to the #endif thereby not including the file again.

    Comment

    • Banfa
      Recognized Expert Expert
      • Feb 2006
      • 9067

      #3
      Once you have added inclusion guards you may well find the code not compiling because of undefined symbols on your classes.

      class A can not use to class B in its definition if class B uses class A in its definition.

      However class A can use a reference(or pointer) to class B in its definition even if class B uses class A in its definition.

      If can do this using a forward declaration. A forward declaration looks something like this

      Code:
      class B;
      It tells the compiler that class B is going to be defined at some future time. This is enough to allow the compiler to create pointers and references to class B but not enough to access the members of class B.

      In the situation I have described the forward declaration to B would be put in the class A header and the class A header would just be included into the class B header.

      Comment

      • donbock
        Recognized Expert Top Contributor
        • Mar 2008
        • 2427

        #4
        There is a typo in weaknessforcat' s code snippet. It should be ifndef rather than ifdef.
        Code:
        #ifndef SUBJECTH
        #define SUBJECTH
        ...
        #endif
        An inclusion guard of this sort is a common idiom among C/C++ programmers.

        One way to handle interdependenci es such as those described by banfa is to put all of your forward declarations, incomplete structure declarations, and related stuff in a third header file that is included by both of the other headers. All three header files have their own inclusion guards. The third header is only included by other header files, never by a cpp file.

        Comment

        • weaknessforcats
          Recognized Expert Expert
          • Mar 2007
          • 9214

          #5
          Originally posted by weaknessforcats
          It should be ifndef rather than ifdef.
          Oops..........

          Comment

          • Banfa
            Recognized Expert Expert
            • Feb 2006
            • 9067

            #6
            Originally posted by weaknessforcats ;
            Oops..........
            That's C++ for you :D

            Comment

            • donbock
              Recognized Expert Top Contributor
              • Mar 2008
              • 2427

              #7
              One last point about this inclusion guard idiom: it is crucial that a unique macro name be used for each header file's inclusion guard. The inclusion guard will malfunction badly if that macro name happens to already be defined for some other purpose.

              Personally, I try to achieve unique names by choosing macro names that match the header filename in capital letters, replacing the period with an underscore. I'm then careful to not define macros of the form foo_H for anything else.

              Comment

              • hype261
                New Member
                • Apr 2010
                • 207

                #8
                Include guards

                You can also use #pragma once instead of the #include guards if your compilier supports it. It is non-standard which limits portability of your code.

                Comment

                Working...