Thread: #include recursion trouble

  1. #1
    GA ichijoji's Avatar
    Join Date
    Nov 2002
    Posts
    179

    #include recursion trouble

    OK, so I'm working on a RPG, and I have a player class and a monster class. I need each of these to use each other, but when I try to #include each one from the other, I get wicked #include recursion and my compiler rolls over and dies. Does anybody know how I can get around this without restructuring my game?
    Last edited by ichijoji; 07-01-2003 at 01:46 PM.
    Illusion and reality become impartiality and confidence.

  2. #2
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Use macros to determine if a header has already been included. This might be in the FAQ but I'm not sure.

    Code:
    #ifndef _MONSTERS_
    #define _MONSTERS_
    
    
    ...body of the header
    
    
    #endif   //end of monsters.h
    Code:
    #ifndef _PLAYER_
    #define _PLAYER_
    
    ..body of the header
    
    #endif  //end of player.h
    Code:
    #include "monsters.h"
    #include "player.h"
    
    ..body of code module


    This example does not show why multiple includes happen, but this system will prevent them from occurring, even if you include monsters or player within each other - like if you need some class definition from player in the monster class and vice versa.

  3. #3
    Pursuing knowledge confuted's Avatar
    Join Date
    Jun 2002
    Posts
    1,916
    Stick them in the same include file silly.
    Away.

  4. #4
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826

    Re: #include recursion trouble

    Originally posted by ichijoji
    OK, so I'm working on a RPG, and I have a player class and a monster class. I need each of these to use each other, but
    Redesign your program. You shouldn't need to classes that depend on eachother. Either that, or make them friends.

    A better method would be to make a 'creature' base class, and derive two types from it.

    But yes, to fix your include issue, do as Bubba describes.
    Hope is the first step on the road to disappointment.

  5. #5
    Registered User
    Join Date
    May 2003
    Posts
    1,619
    I think they should probably be derived from the same base as well.

    However, in general, you should design your programs such that your headers #include as few other user-created headers as necessary. It vastly reduces compile time and other issues.

    You should only #include something when you need the type to be complete (i.e. defined). If you don't need a complete type, use a forward declaration.

    From another post I made on that subject:

    Also, make your own headers #include as few other headers as possible. If you don't need a complete type, don't include the header, just forward declare the classes.

    For example, this would be unnecessary:

    Code:
    A.H
    #ifndef __A_H_INCLUDED_____
    #define __A_H_INCLUDED_____
    #include "b.h" // assume this defines class B
    
    class A{
    private:
       B& myBObject;
       B* myBPtr;
    public:
       explicit A(B&);
       void otherFunction(B*);
       B f2();
       void f3(B);
    };
    
    #endif
    Here, you will notice that in the above code, it was NOT necessary for B to be a complete type. B is only used as a reference (B&), a pointer (B*), or a parameter/return type, so it can legally still be an incomplete type (a type that has been declared but not defined). There are no member variables of type B (only type B& or B*), and B is not a base class of A. Further, we have no containers of B that might need to know its definition. So instead of defining B by the include, we declare it instead:

    Code:
    A.H
    #ifndef __A_H_INCLUDED_____
    #define __A_H_INCLUDED_____
    class B; //declares class B
    
    class A/*A is declared here*/{
    private:
       B& myBObject;
       B* myBPtr;
    public:
       explicit A(B&);
       void otherFunction(B*);
       B f2();
       void f3(B);
    }/*A is defined here*/;
    
    #endif
    In the code above, I also show where A is declared and defined. Note A can be declared as often as you like; it should only be defined in one header. Learn all the rules about incomplete types; often only a declaration is needed, not a definition.

    Now, A.CPP will certainly need to include B.H (A.CPP will need B to be a complete type, because it will want to use member functions or data of B, and it must know how to copy B objects). But the goal is to make your headers (.h) files include as few other headers as possible; put your includes in the .CPP files only when possible.

    Never #include another header of yours unless you actually need a complete type. For an incomplete type, just forward declare it.

    You can also use tricks like the PIMPL idiom to hide your class's "private parts", which will probably cut down drastically on the need for full definitions of classes.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. trouble with hotns() ntohs()
    By ZaC in forum C Programming
    Replies: 7
    Last Post: 06-25-2008, 02:39 PM
  2. Recursion program trouble... ?
    By Beachblue in forum C Programming
    Replies: 7
    Last Post: 06-19-2008, 01:43 PM
  3. Socket programming
    By kahad in forum C Programming
    Replies: 3
    Last Post: 12-14-2006, 04:37 PM
  4. Read and write hanging
    By zee in forum C Programming
    Replies: 8
    Last Post: 08-03-2004, 11:19 PM
  5. help with finding lowest number entered
    By volk in forum C++ Programming
    Replies: 12
    Last Post: 03-22-2003, 01:21 PM