CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 14 of 14
  1. #1
    Join Date
    May 2009
    Posts
    5

    Including a class within another class

    Hi All,

    I'm still very new to C++ so apologies in advance if I am not too clear in my description of my problem.

    I am making a text based drug dealing game which has an Class called Enemy which contains all the information you might expect to find about an enemy (health and weapon stats). This is defined in a .h and .cpp file within my project. I am then making a class called Location which contains information on how many customers want drugs of each type, the maximum number of customers for each drug type and so on. At each location I want to have an array of enemies so that the player must fight off a group of enemies before they can start to deal on that turf.

    So I have my Enemy class working properly and then within the Location class I want to add something like this:

    Enemy enemyGang[5];

    So I have an array of five enemies which I can then tweak each turn based on some simple randomisation so the gang is not always identical.

    When I compile this within Code::Blocks I get the following error.

    `Enemy' does not name a type

    I have written #include "Enemy.h" at the top of the Location.h file so it should know what an Enemy class is. What am I doing wrong?

    Location.h:

    Code:
    #ifndef LOCATION_H_INCLUDED
    #define LOCATION_H_INCLUDED
    #include "Enemy.h"
    
    class Location
    {
    
    private:
    
    public:
    string name;
    
    Enemy enemies[5];
    
    Location();
    
    };
    #endif // LOCATION_H_INCLUDED

    I'd like to make an array of Locations that would be my map and I would access the enemy gang thus.

    locations[0].enemies[0].name = "Gangster1";


    Am I doing something fundamentally wrong? Can you not include a predefined class within another class?

    Any help would come as a great relief!

    Thanking you in advance.

    -Liam
    Last edited by Diamo; May 23rd, 2009 at 01:18 PM.

  2. #2
    Join Date
    Nov 2006
    Location
    Australia
    Posts
    1,569

    Re: Including a class within another class

    You should be qualifying the string type with std:: - that should give you a compile error. Could we see your Enemy .h and .cpp files?
    Good judgment is gained from experience. Experience is gained from bad judgment.
    Cosy Little Game | SDL | GM script | VLD | Syntax Hlt | Can you help me with my homework assignment?

  3. #3
    Join Date
    May 2009
    Posts
    5

    Re: Including a class within another class

    Yeah, I have been 'using namespace std;' but you are of course correct.

    Enemy.h :
    Code:
    #ifndef ENEMY_H_INCLUDED
    #define ENEMY_H_INCLUDED
    #include "globals.h"
    #include <iostream>
    #include "randomNameGenerator.h"
    
    //These are also in my globals.h file but don't seem to work properly so I redefine here.
    #define totalNumberOfWeapons 2
    #define melee 0
    #define pistol 1
    
    #define inventorySize 3
    #define totalNumberOfDrugs 6
    /*Number of drugs where the reputaion is traced*/
    #define drugsWithReps 3
    
    using namespace std;
    
    class Enemy{
    
    private:
    
    public:
    
    /*used to check whether they are alive i.e. slot is free or not*/
    bool isAlive;
    
    /*The enemy's name*/
    string name;
    
    /*Stats for fighting*/
    int health;
    
    /*used in my JRPG style fight engine*/
    int framesLeft;
    int equipedWeapon;
    
    struct weaponStruct{
        bool hasWeapon;
        int weaponType;
        string weaponName;
        int damage;
        int clipSize;
        int ammo;
        bool isReloading;
        };
    
    struct weaponStatStruct{
        int aimTime;
        int accuracy;
        int reloadingTime;
        };
    
    weaponStruct weapons[totalNumberOfWeapons];
    weaponStatStruct weaponStats[totalNumberOfWeapons];
    
    
    /*Enemy constructor*/
    Enemy();
    
    };
    
    #endif // ENEMY_H_INCLUDED


    Enemy.cpp :

    Code:
    #include "Enemy.h"
    
    using namespace std;
    
    
    Enemy::Enemy(){
    
    /*Initialise standard variables*/
    
    /*Create them dead as they will mostly be filling blank arrays*/
    isAlive = false;
    health = 100;
    name = "";
    
    weapons[melee].weaponType = 0;
    weapons[melee].hasWeapon = true;
    weapons[melee].ammo = 1;
    weapons[melee].clipSize = 2; //clipSize of 2 means melee never has to reload*/
    weapons[melee].damage = 5;
    weapons[melee].isReloading = false; //Melee will never reload
    weapons[melee].weaponName = "Fists";
    
    weaponStats[melee].aimTime = 8;
    weaponStats[melee].reloadingTime = 0; //Should never need this
    weaponStats[melee].accuracy = 100;
    
    
    weapons[pistol].weaponType = 1;
    weapons[pistol].hasWeapon = false;
    weapons[pistol].ammo = 0;
    weapons[pistol].clipSize = 3;
    weapons[pistol].damage = 15;
    weapons[pistol].isReloading = false;
    weapons[pistol].weaponName = "Three-Shooter";
    
    weaponStats[pistol].aimTime = 5;
    weaponStats[pistol].reloadingTime = 15;
    weaponStats[pistol].accuracy = 50;
    
    }
    I also create an array of type Enemy in my globals but I did a rather hatchet job with some code I found on the internet that I dont really understand and did not work when I tried to copy it into my Location class. I used this code before I implimented a location system because I basically needed an array to test my combat system. So here is how I did it using my globals.h and globals.cpp which I made available to any header that needed it.

    globals.h :

    Code:
    #ifndef GLOBALS_H_INCLUDED
    #define GLOBALS_H_INCLUDED
    #include <iostream>
    #include "Dealer.h"
    #include "Player.h"
    #include "Enemy.h"
    
    
    /*Drug definitions*/
    #define totalNumberOfDrugs 6
    #define weed 0
    #define speed 1
    #define acid 2
    #define heroin 3
    #define cocaine 4
    #define ecstacy 5
    
    /*Weapon definitions*/
    #define totalNumberOfWeapons 2
    #define melee 0
    #define pistol 1
    
    /*Maximum number of enemies allowed*/
    #define maxEnemyGangSize 5
    
    extern class Dealer dealer1;
    extern class Player player1;
    
    /*No idea what this code does but it worked when I added it*/
    extern class Enemy enemyGang[maxEnemyGangSize];
    
    #endif // GLOBALS_H_INCLUDED

    globals.cpp

    Code:
    #include "globals.h"
    
    Dealer dealer1;
    Player player1;
    
    /*This also proved necessary to get my code to compile and
    have a globally available array of enemies*/
    Enemy enemyGang[maxEnemyGangSize];

    I don't know what all this "extern class Enemy enemyGang[maxEnemyGangSize];" in the header actually does but it worked so I got working on my game and put it to the back of my mind. It appears I need both declarations (in .h and .cpp) to make this array statement compile properly and to make this array available to any other code that needs the array of enemies. I know I'm going a bit off topic here but I thought I best explain. I think I need a better overall understanding of the way classes work though.

    Thanks for getting back so quickly and I hope you can be of further help.

    -Liam
    Last edited by Diamo; May 23rd, 2009 at 01:08 PM.

  4. #4
    Join Date
    Nov 2006
    Location
    Australia
    Posts
    1,569

    Re: Including a class within another class

    Most programming forums where you are posting code samples will expect you to use code tags. I am trying to read through your code but I can't make sense of it. Please edit your post to include code tags.
    Good judgment is gained from experience. Experience is gained from bad judgment.
    Cosy Little Game | SDL | GM script | VLD | Syntax Hlt | Can you help me with my homework assignment?

  5. #5
    Join Date
    Dec 2008
    Posts
    56

    Re: Including a class within another class

    Never place a "using namespace" directive in a header file; it is considered poor programming practice.

    Additionally, it would be better to define an enum or another type (e.g. static const unsigned int) in lieu of the #define macros.

    Also consider using an STL vector in lieu of the arrays; these should be declared within a class, or your main() function. Defining global variables is the first indicator of a poor design.

  6. #6
    Join Date
    May 2009
    Posts
    5

    Re: Including a class within another class

    Hi Guys,

    Firstly, sorry about the non-use of the code tag, I've updated both my posts. I hope they are a bit more readable now.

    Further points:
    1. Removed "using namespace std" from the header. I included this during my desperate attempt to get my globals.h to 'understand' my Enemy class type so I could make an array with it.

    2. I read up on #define and you are right, it could lead to some problems so I will use a static definition in future.

    3. I have heard that using global variables is a bad idea but I am still having trouble getting my head around designing software without them. I work for a major games company and one of the level designers said they used them so I just went ahead and made a globals file. As I am attempting to learn the C++ language through this project I will hopefully get better as I move on. Right now I can't imagine how you would write a game without a global variable of the 'player' though!

    4. I tried using a vector of type Enemy in place of my array structure in my Location class with the following code.

    Code:
    #include "Enemy.h"
    #include <vector>
    
    class Location
    {
    
    private:
    
    
    vector<Enemy> enemies;
    
    Location();
    
    };

    I still recieved the compilation error:

    error: `Enemy' was not declared in this scope

    My question seems fairly straight forward. If I include a .h file that defines a class why is that class then not recognised as a variable type?

    In both my globals.h and in the above Location.h I '#include' the class definition in "Enemy.h" but they don't recognise them as a straight forward variable type. Even when I declare a single instance of the class type in my globals files I have to write the following to make it work:

    .h:
    Code:
    extern class Enemy enemy1;
    .cpp:
    Code:
    Enemy enemy1;
    Is there some sort of fundamental problem I am missing?

    Again, thanks for your advice and help so far. I hope I am making sense.

    -Liam
    Last edited by Diamo; May 23rd, 2009 at 01:46 PM.

  7. #7
    Join Date
    Dec 2008
    Posts
    56

    Re: Including a class within another class

    Quote Originally Posted by Diamo View Post
    ... I can't imagine how you would write a game without a global variable of the 'player' though!
    One of the keywords, or noun, in your statement is 'game'. You should have a class object that represents the Game, and it is within there, that you would declare your Player object(s), game-board, etc.

    Quote Originally Posted by Diamo View Post
    4. I tried using a vector of type Enemy in place of my array structure in my Location class with the following code.

    Code:
    #include "Enemy.h"
    #include <vector>
    
    class Location
    {
    
    private:
    
    
    vector<Enemy> enemies;
    
    Location();
    
    };

    I still recieved the compilation error:

    error: `Enemy' was not declared in this scope
    Your header for Location looks fine, although you are missing the std:: qualifier for the vector<Enemy> declaration. Also, it seems odd that your Location() constructor is defined as private; do you intend to have another constructor? If not, good luck instantiating one of these objects.

    In your previous post, the constructor for Enemy was also declared private in Enemy.h; this is what is probably causing the compilation error.

    Quote Originally Posted by Diamo View Post
    Code:
    extern class Enemy enemy1;
    This is not necessary... ever!

    Quote Originally Posted by Diamo View Post
    .cpp:
    Code:
    Enemy enemy1;
    Is there some sort of fundamental problem I am missing?
    See the comments above concerning the private constructors.

  8. #8
    Join Date
    May 2009
    Posts
    5

    Re: Including a class within another class

    Hi All,

    It has become clear to me after designing a short test program that I am doing something fundamentally wrong in the design of my project. I tried making a short test project, stripped to the minimum with the following files.

    Location.h
    Enemy.h
    globals.h

    Location.h
    Enemy.h
    globals.cpp
    main.cpp

    Inside globals.h I made an array of classs type Location that included an array of class type Enemy within its definition. When I compiled this program it crashed. After I took the following statement out of globals.cpp it worked: "#include globals.h".

    Clearly I have a flawed understanding of putting together a large C++ program. I will go back and try to clear out the headers and code files of unnecessary #include statements and perhaps re-organise my project entirely. I am sure this is due to me learning as I go, already I notice my code earlier is clumsy and ill thought out compared to my later code and the organisation of headers and code files is better later on.

    Thanks for your help everyone.

  9. #9
    Join Date
    Dec 2008
    Posts
    56

    Re: Including a class within another class

    Hopefully you will see this post; below is the minimum to get you on your way...

    Location.h:
    Code:
    #ifndef LOCATION_H
    #define LOCATION_H
    
    #include "Enemy.h"
    #include <vector>
    
    class Location
    {
    public:
       Location();
    
       // ...
    
    private:
       std::vector<Enemy> enemies;
    };
    
    #endif
    Location.cpp:
    Code:
    #include "Location.h"
    
    Location::Location()
    {
    }
    
    // ...
    Enemy.h:
    Code:
    #ifndef ENEMY_H
    #define ENEMY_H
    
    #include <string>
    #include <vector>
    
    enum WeaponType { MELEE, PISTOL };
    
    
    class Enemy
    {
    public:
       Enemy();
    
       // ...
    
    private:
       bool isAlive;
       std::string name;
       int health;
       int framesLeft;
       int equipedWeapon;
    
       struct WeaponInfo {
          bool hasWeapon;
          WeaponType weaponType;
          std::string weaponName;
          int damage;
          int clipSize;
          int ammo;
          bool isReloading;
       };
    
       struct WeaponStats {
          int aimTime;
          int accuracy;
          int reloadingTime;
       };
    
       struct Weapon {
          WeaponInfo info;
          WeaponStats stats;
       }
    
       std::vector<Weapon> weapons;
    };
    
    #endif
    Enemy.cpp:
    Code:
    #include "Enemy.h"
    
    Enemy::Enemy()
    {
    }
    
    // ...
    Main.cpp
    Code:
    #include "Location.h"
    
    int main()
    {
    }
    This should all compile. Personally, though, I would not have defined the Weapon/WeaponStats structs within the Enemy class because these should be able to be used elsewhere. For instance, for a game pitting two players against each other, say one called Friend, the other Foe, each of these players should have an arsenal of weapons.

    P.S. If you know that you are going to have a fixed quantity of elements, say in the case of players, then there is no need to define a vector. Just use an array of fixed-size.

    The rule of thumb is to capitalize all letters of static variables and enums, thus making them standout against normal variables, which value is alterable.

  10. #10
    Join Date
    May 2009
    Posts
    5

    Re: Including a class within another class

    Bloody hell, thanks man, that was really nice of you to post that full explanation. I'm re-writing as we speak and as you suggested I'm making a weapon a class. A lot of the code I wrote was just placeholder/copy and paste stuff so that I could get down to the combat engine which is what I was really interested in working on I've started from the beginning again with a much more object oriented approach and I'm trying to build the skeleton of the world in classes before I hang the meat on the code. Seems like a better way to do it but it sure is difficult conceptualising the world and the relationships within (basically because I had no clear plan). I may well be back with further questions!

    Thanks a ton to you all.

  11. #11
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    Re: Including a class within another class

    Quote Originally Posted by dwhitney67
    The rule of thumb is to capitalize all letters of static variables and enums, thus making them standout against normal variables, which value is alterable.
    It may be wiser to adopt a different naming convention instead of fully capitalising such names since that convention is already typically used to name macros, and macros do not respect scope.
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  12. #12
    Join Date
    Dec 2008
    Posts
    56

    Re: Including a class within another class

    Quote Originally Posted by laserlight View Post
    It may be wiser to adopt a different naming convention instead of fully capitalising such names since that convention is already typically used to name macros, and macros do not respect scope.
    Most s/w development projects have standards that differ from your opinion. But at the end of the day, do whatever pleases you (and your peers). Don't cry though when someday you have to maintain a huge s/w project and cannot discern the difference between a macro, a class name, a local variable, a static const, or enum value.

  13. #13
    Join Date
    Aug 2007
    Posts
    858

    Re: Including a class within another class

    Quote Originally Posted by dwhitney67 View Post
    Don't cry though when someday you have to maintain a huge s/w project and cannot discern the difference between a macro, a class name, a local variable, a static const, or enum value.
    If your code is so convoluted that that's a major problem, you have much bigger problems than just your naming convention for enums.

  14. #14
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    Re: Including a class within another class

    Quote Originally Posted by dwhitney67
    Most s/w development projects have standards that differ from your opinion.
    In my experience, the decision is more divided among projects that you make it. But then I have limited experience. However, Stroustrup does state in his answer to the FAQ So, what's wrong with using macros? that "conventions such as having macros (and only macros) in ALLCAPS helps", for the same basic reason that I have cited.

    Quote Originally Posted by dwhitney67
    Don't cry though when someday you have to maintain a huge s/w project and cannot discern the difference between a macro, a class name, a local variable, a static const, or enum value.
    Considering that you are proposing to make enums and class constants follow the same naming convention as macros, I'd say that that would apply to you
    I, on the other hand, recommended that they use different naming conventions, but left the details unspecified.
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured