Access of members (previously "Inheritance problem").

Hello!
I was trying to allow my "Enemy" class in the code to inherit the public information (and with it, protected) from the "MapFunctions" class in my program, but the compiler does not recognize that it is a class. It says: "error: expected class-name before '{' token" (referring to the part of Enemy.h that says "public MapFunctions") The relevant code is below:

Enemy.h:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include "AemRandW.h"
//........
........\\
using namespace std;
//........
........\\
class Enemy: public Player, public MapFunctions {
    public:
    Enemy();
        void setStats(int a, int b, int c, int d, int e, int f, int g);
        void setApproachText();
        void DetermineFightFirst();
        virtual void attack() = 0;
        ~Enemy();
    protected:
        int enemyAttack, enemyDefence, enemyMagic, enemyHealth, enemyMaximumHealth, enemyMoney, enemySpeed, damage;
};


AemRandW.h:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
using namespace std;

class MapFunctions{
    public:
    MapFunctions();
void MapRead();
void SetLevel(int levelvalue);
void FindStart();
void MapDelete();
void PlayMap();
void EquateTextPrint();
void DirectionCheck();
    ~MapFunctions();
    protected:
int level;
    private:
int ** Map;
int locx, locy, rows, cols, StartTextSize, DirectionSpecifierCount;
bool mapCompletion, DirectionSpecifier[4], IgnoreSpecifier,  EnemyFightFirst;
string StartText;
};


If any other information is required, please tell me and I shall post it.
Could anybody please tell me what the (likely obvious) problem is, please?
Last edited on
You are misusing inheritance. And as a result you have bigger design problems than the one you are describing.

Inheritance forms an "is a" relationship. For example, if "Dog" is a parent class, then "Poodle" might be a child class, because a Poodle "is a" Dog.

Your enemy is inheriting from Player and MapFunctions, which implies that an Enemy is a Player (nonsense), and an Enemy is also a MapFunctions (also nonsense -- particlarly because a MapFunctions class doesn't really make much sense).


As for the actual error, it looks like it isn't recognizing "Player" as a class. Did you #include player.h?
Yes I did, and it recognized it. I originally just used it for that (e.g. the Goblin and Orc both inherit from the enemy class as they're both enemies), but I began to get used to using it for more (and it worked)
when I couldn't understand friend functions very well. Could you show me how to use friend functions instead (if this is more appropriate), please?
You likely don't need any friends. Friends are when you are creating two or more very closely-knit classes (like a container class and its iterator classes). You have nothing like that here so don't worry about it.

You need to rethink your class hierarchy. I would recommend something like this:

GameObject (parent class)
Player (derived from GameObject)
Enemy (derived from GameObject)
Orc (derived from Enemy)
Goblin (derived from Enemy)
etc

Note that since GameObject is at the top of the hierarchy, all those classes are considered game objects.

Also note that game object is not a map. The map should be an entirely different and unrelated class. You could have a pointer or reference to the map in your GameObject class, so that all game objects can interact with the map, but the map should not exist in that class -- otherwise each object will have its own map, which is not what you want.
I do not see the MapFunctions constructor definition The error can be the result of that you forgot to specify class name before the constructor when you were defining it. That is instead of

1
2
3
4
MapFunctions()::MapFunctions()
{
// some code
}

you could write

1
2
3
4
MapFunctions()
{
// some code
}


Last edited on
@vlad from moscow
I used a separate header and implementation file - the constructor code being in the implementation file.

@Disch
I am really tired and can not think very well right now. Would it be possible that you could show me an example, please (there would have to be some way in which the player's stats and enemy's stats can be compared)?
Edit: When you say about the map being stored in an entirely different class, it is stored in a dynamically allocated 2D array and does not contain the player's coordinates. These are contained by the variables "locx" and "locy". Enemy spaces (represented by certain numbers) are changed to path once the enemy has been killed and the starting position is changed to a path tile by the program (the program using the starting position to figure out the initial "locx" and "locy" values).
Last edited on
The only idea that comes is that you declared somewhere a function with the same name as your class MapFunctions
Exispistix wrote:
Would it be possible that you could show me an example, please (there would have to be some way in which the player's stats and enemy's stats can be compared)?


Well players and enemies have mostly the same stats, right? Since both players and enemies are derived from GameObject, those stats can go in GameObject, and that class can do all the comparisons:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class GameObject
{
//...
   int attack;
   int defense;
   int health;
   //  ... etc
};

// Then you can have a member function to attack another GameObject:
void GameObject::AttackObject(const GameObject& opponent)
{
  int damage = attack - opponent.defense;
  if(damage < 0)
    damage = 0;

  opponent.defense -= damage;
  // (or something like that -- your damage calculation I'm sure will differ)
}



Exispistis wrote:
When you say about the map being stored in an entirely different class, it is stored in a dynamically allocated 2D array and does not contain the player's coordinates.


Who "owns" that 2D array (ie, who allocates it, loads it, deletes it)? From the looks of your code, I thought your MapFunctions class was the owner. If that is the case, then deriving players/enemies from MapFunctions is not a great idea.

That said, a map is a complex concept and should be more than just a simple 2D array. It should be encapsulated inside a class. The question now is how do you make that class, and how do your other classes access it?

Very generally speaking, there are 3 major kinds of relationships your classes will have. Determining how to make these classes interact is often as simple as identifying which of the below relationships match the best and writing the implementation to match. Of course, it's not always so cut-and-dry, but these rules are a good "general case" and will work most of the time:

1) ClassA "is a" ClassB Inheritance

Poodle "is a" Dog
Orc "is an" Enemy
Player "is a" GameObject
etc

 
class Orc : public Enemy { /*...*/ };


In these cases, the parent class is a general class, and the child class is a more specific kind of that general class. It can get more general the higher up the hierarchy you go:
Poodle is a Dog, Dog is an Animal, Animal is a LivingBeing, etc.

The advantage to using inheritance is that you can write code that works for the general parent class, and it will apply to ALL of the more specific child classes. That is, any code written for 'Dog' will apply to Poodles, Greyhounds, Dalmations, etc. But things specific to only one kind of Dog can be kept in the child classes.


2) ClassA "has a" ClassB or ClassA "owns a" ClassB Composition

A Player "owns a" Weapon. A Player "has a" health value.

1
2
3
4
5
6
class Player
{
  //...
  Weapon weapon;
  int health;
};


Here, these things are owned by the Player. In this case you do not derive Player from any other classes (deriving from Weapon would make Player inherit weapon properties, which might be functional, but it implies that a Player "is a" weapon, which is nonsense). Rather, you simply give the player member variables.

The Player class then "owns" those variables and is responsible for keeping them in the correct state. That is, if allocating memory is required, then the Player class should be the only part of your program allocating/freeing memory because it's the owner. It should also be the only class that is modifying or really even accessing these values.



This 3rd one is a little trickier to explain. It's also the most complicated to implement:
3) ClassA "knows of a" ClassB or ClassA "uses an existing" ClassB accessing by pointer/referece

Here we have a Player and some Enemies. We also have a Map. But how does "Map" fit in with the other classes?

A Player is not a Map, so inheritance doesn't work.
Also, a Player does not own the Map, so using composition also wouldn't fit very well.

The idea here, is that Map is owned elsewhere, and Player/Enemy need access to it. They know about it, and interact with it, but they do not actually own it themselves.

1
2
3
4
5
6
7
8
9
10
11
12
class Map
{
  /* ... */
};

class Player
{
  /*...*/
  Map* map;
  int posX;
  int posY;
};


This is tricky because now you have external classes referring to an object they don't own, which makes things more complicated. Particularly, you need to make sure that none of these classes are still using the Map when the Map is destroyed, or else their pointer will go bad.

This is most easily accomplished by having all of these classes owned by a larger class which manages the interactions between them. In games I often use a "GameWorld" or similar class.

1
2
3
4
5
6
class GameWorld
{
  //...
  Map map;  // the game world owns the map
  std::list<GameObject*> objects;  // it also owns a all objects that exist in the world
};


This way, the GameWorld class can manage the "big picture" stuff and the smaller Player/Enemy/GameObject/Map classes only have to worry about their respective roles.




Anyway, blah blah blah. Tl;dr. Just spitballing ideas. Take whatever you want from this post.
Last edited on
Topic archived. No new replies allowed.