Классы как ошибка параметров - PullRequest
0 голосов
/ 02 мая 2011

В Weapon.h, когда я пытаюсь взять класс «Entity *» в качестве параметра, при компиляции он говорит «Синтаксическая ошибка: идентификатор« Entity »». Кроме того, когда я переворачиваю текст «цель», Visual C ++ Express 2010 дает мне текст «* цель». Класс Entity в порядке, и я уверен, что он включен правильно.

(я не буду публиковать Player.h, так как он не нужен - см. Library.h - но он имеет защиту заголовка и включает 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

Ответы [ 4 ]

5 голосов
/ 02 мая 2011

В C ++ классы должны быть объявлены до , на которые они ссылаются. Вы #include -ing Weapon.h в Entity.h, но на данный момент компилятор не знает о существовании class Entity.

Вам нужно будет либо изменить порядок объявления вещей, либо добавить предварительное объявление «выше» class Weapon. Это может быть просто:

class Entity;

Это говорит компилятору, что существует такое имя, как Entity. Тем не менее, он не сообщает ему ничего о том, какие члены у него есть, поэтому вы не можете ничего с ним сделать, кроме как объявить переменные Entity * и Entity & и передать их.

1 голос
/ 02 мая 2011

Ваши заголовки включают друг друга, потому что ваши классы ссылаются друг на друга. (Но ваш компилятор не страдает от переполнения стека из-за вашей защиты включения - это хорошо!)

Вы должны расположить заголовочные файлы иерархически, то есть в верхней части находятся файлы, которые #inc ничего не включают, и файлы ниже, которые включают некоторые из верхних и так далее в иерархии. Но ни в коем случае не должно быть «петель».

Чтобы разорвать ваши циклы в коде, любые классы, которые ссылаются друг на друга, должны заранее объявить любые взаимные зависимости и ссылаться только на имена зависимостей, а не на их члены.

, например

Entity.h

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

Weapon.h

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

Обратите внимание, что Weapon.h относится только к Entity*.

Вам нужно будет определить int Weapon::DamageTarget(Entity* target) в Weapon.cpp

1 голос
/ 02 мая 2011
#include <entity.h>

Или заранее объявить только в шапке

class Entity;

Это делает компиляцию немного быстрее (вам все еще нужно включить ее для использования в реализации).

0 голосов
/ 02 мая 2011

Weapon.h не включает в себя Entity.h или что-либо, что его включает в себя.Следовательно, он не знает о классе Entity.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...