0

In Weapon.h, when I try and take a class 'Entity*' as a parameter, it says "Syntax error: identifier 'Entity'" when I compile. Additionally when I roll over the text 'target', Visual C++ Express 2010 gives me the text " *target". The Entity class is fine and I'm pretty sure it's included correctly.

(I won't post Player.h as it's unnecessary - see Library.h - but it has a header guard and includes Entity.h)

Library.h:

#ifndef _LIBRARY_
#define _LIBRARY_
#include <iostream>
#include <string>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <cstdarg>
#include <vector>
#include <ctime>
#include <cmath>
#include <cstdlib>
#include <map>
#include <exception>
#include <sstream>
//file includes
#include "Globals.h"
#include "Player.h"
#include "Exception.h"
#include "Weapon.h"
#include "Armour.h"
#include "Consumable.h"
//prototypes that require "Library.h"
bool Poglathon(std::vector<std::string>& text,Player *player);
bool PoglathonTown(std::vector<std::string>& text,Player *player);
std::map<std::string,Weapon*> init_weapons(void);
std::map<std::string,Armour*> init_armour(void);
std::map<std::string,Consumable*> init_consumables(void);
#endif //__LIBRARY__

Weapon.h:

#ifndef _WEAPON_H_
#define _WEAPON_H_
#include "Shopable.h"
class Weapon : public Shopable{
private:
 int Damage;
public:
 Weapon(int c,int d,std::string n) : Shopable(c,n),Damage(d){}
 std::string getDesc() const{
 return getName()+"\t"+tostring(Damage)+"\t"+tostring(Cost);
 }
 int getDamage() const{return Damage;}
 int DamageTarget(Entity* target){
 int DamageDealt = 0;
 //do damage algorithm things here
 return DamageDealt;
 }
};
#endif

Shopable.h:

#ifndef _SHOPABLE_H_
#define _SHOPABLE_H_
#include "Library.h"
class Shopable{
protected:
 std::string Name;
 int Cost;
 std::string Description;
public:
 Shopable(int c, std::string n):Cost(c),Name(n){}
 std::string getName() const{return Name;}
 int getCost() const {return Cost;}
 virtual std::string getDesc() const = 0;
};
#endif

Entity.h:

#ifndef _ENTITY_
#define _ENTITY_
#include "Library.h"
#include "Weapon.h"
#include "Armour.h"
#include "Consumable.h"
class Entity{
public:
 void printStats() const;
 void heal(double health);
 std::string name;
protected:
 //player stats
 double str; //strength
 double wis; //wisdom
 double ref; //reflex
 double hp; //health points
 double maxHp; //maximum health points
 double i; //initiative
 double inte; //intelligence
 double c; //courage
 int gold; //gold
 int xp; //experience
 int ap; //armour points
 int wd; //weapon damage
 int lvl; //level
 int sp; //skill points
 Weapon* weapon;//weapon
 Armour* cArmour;//current armour
};
#endif
asked May 2, 2011 at 12:15
6
  • Not a solution, but a comment: you might want to try and move unnecessary includes away from the headers and into the implementation files, replacing them with forward declarations: for example, there's really no need for Entity.h to include Weapon.h or Armour.h when it could just forward declare the classes. Perhaps that kind of modification would make the root of this problem easier to find, too. Commented May 2, 2011 at 12:21
  • what @Heandel said. And culling the includes would make it plainer. Commented May 2, 2011 at 12:22
  • Forward declare the classes? And @Heandel, I posted all the code that I thought might be the cause of the problem. I just posted the lot instead of shortening it, sorry. Commented May 2, 2011 at 12:29
  • @Pig Head -- When you ask for assistance, please include a Short, Self Contained, Correct (Compilable), Example (sscce.org). Had your example been short and self-contained, you might very well have found the problem yourself. Commented May 2, 2011 at 14:38
  • 1
    Yes, @Pig Head, that is a problem. But it is a problem that you are better equipped to solve than we are. Start by deleting a few lines at a time, which lines you suspect are unrelated. Delete functions that aren't called, class members that don't illustrate the problem. And, at each step, recompile your program to see if the error is still present. Eventually, either 1) you've discovered precisely which deleted line caused the problem, or 2) you've create a sample so short as to make it obvious which line causes the problem. Commented May 2, 2011 at 15:32

4 Answers 4

5

In C++, classes must be declared before they are referenced. You are #include-ing Weapon.h in Entity.h, but at that point, the compiler doesn't know about the existence of class Entity.

You will either need to change the order in which things are declared, or add a forward declaration "above" class Weapon. It can simply be:

class Entity;

That tells the compiler that there is such a name as Entity. However, it doesn't tell it anything about what members it has, so you can't actually do anything with it, other than declare variables of Entity * and Entity &, and pass them around.

answered May 2, 2011 at 12:19

1 Comment

How can I change the order in which things are declared? Can you explain that in more detail please?
1

Your headers include each other because your classes refer to each other. (But your compiler doesn't suffer from a stackoverflow because of your include guards - that's a good thing!)

You should arrange your header files hierarchically, ie there are files at the 'top' which #include nothing and files 'below' which include some of the top ones and so-on down the hierarchy. But at no point should there be 'loops'.

In order to break your loops in your code, any classes that refer to each other should forward declare any mutual dependencies and only refer to dependency names and not their members.

e.g.

Entity.h

class Weapon;
class Entity{
 ...
 Weapon* weapon;
};

Weapon.h

class Entity;
class Weapon{
 ...
 int DamageTarget(Entity* target);
};

Notice how Weapon.h only refers to Entity*.

You will need to define int Weapon::DamageTarget(Entity* target) in Weapon.cpp

answered May 2, 2011 at 12:47

2 Comments

How can I avoid a loop if there's a file which includes everything and everything needs to include? (Library.h)
@PigHead: There's always a way. In the case of Library.h I would guess that you can delete most lines. The only includes it needs are vector and string. The rest can be forward declared.
1
#include <entity.h>

Or forward-declare only in the header

class Entity;

This makes compilation a bit faster (you still need to include it to use in the implementation).

answered May 2, 2011 at 12:21

Comments

0

Weapon.h doesn't #include Entity.h, or anything that recursively includes it. Therefore, it doesn't know about the class Entity.

answered May 2, 2011 at 12:19

1 Comment

Weapon.h includes Shopable.h which includes Library.h which includes Player.h which includes Entity.h.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.