0

我有一个包含 20 多个类/头文件的程序。一切都很顺利,直到我昨天开始做一些改变。从字面上看,我花了很长时间才发现我需要在其中一个标题上进行前向声明。虽然我昨天有同样的工作并且它没有使用类的前向声明。

我让它编译并正确运行。我尝试再添加一种方法。我又开始遇到所有这些可怕的错误!就像我说的,昨天所有这些东西都在工作,不知何故我做了一个改变,并不断收到错误说“生物尚未被声明”,即使我没有改变那个类或任何东西..以及同样的错误其他类和这些类的其他对象。

标头包含在它说错误所在的文件中 - 我什至可能添加了额外的包含只是为了尝试一下。这太令人沮丧了,我花了几个小时试图弄清楚如何回到昨天的状态。我尝试简单地添加另一个功能,同样的事情发生了!!请帮助我解决这种持续的挫败感。这是我得到的当前错误:

g++ -c Ammunition.cpp -o Ammunition.o -std=c++0x
g++ -c Armor.cpp -o Armor.o -std=c++0x
g++ -c Consumable.cpp -o Consumable.o -std=c++0x
g++ -c Creature.cpp -o Creature.o -std=c++0x
In file included from DungeonLevel.h:4:0,
             from Creature.h:5,
             from Creature.cpp:1:
Tile.h:15:19: error: ‘Creature’ has not been declared
Tile.h:16:2: error: ‘Creature’ does not name a type
Tile.h:38:2: error: ‘Creature’ does not name a type
In file included from DungeonLevel.h:7:0,
             from Creature.h:5,
             from Creature.cpp:1:
Player.h:9:32: error: expected class-name before ‘{’ token
make: *** [Creature.o] Error 1

这是错误所在的头文件和片段

地牢等级.h

#include "Tile.h"
#include <vector>
#include <random>
#include "Player.h"

class Player; //This is how I fixed the error that took me all day when "Player" was not
              //declared. If you take it out, You'll get error "Player not declared"
class DungeonLevel {
public:
    DungeonLevel(int iWidth, int iHeight, std::mt19937 & randomGen);
    ~DungeonLevel(void);

    void dump();
    char at(int x, int y);

    void placeInGame(Player& playerToPlace, std::mt19937 & randomGen);
    int getWidth();
    int getHeight();

private:
    std::vector<std::vector<Tile>> m_vvTiles; //Tile was char

};

地牢关卡.cpp

#include <iostream>
#include <random>
#include "Tile.h"
#include "DungeonLevel.h"
#include "Player.h"

using namespace std;


void DungeonLevel::placeInGame(Player & playerToPlace, std::mt19937 & randomGen$
    int x;
    int y;
    do {
            y = randomGen() % 20;
            x = randomGen() % 79;
    } while (m_vvTiles[y][x].getDisplayChar() != '.');

    m_vvTiles[y][x].setCreature(&playerToPlace);
}
//Then other code that I don't think is needed

生物.h

#include "Entity.h"
#include "DungeonLevel.h"

class Creature : public Entity {

public:
    Creature(void);
    virtual ~Creature(void);

    virtual void dumpObject();
    virtual void dumpObjectData();
    virtual void writeFragment(std::ostream & output);
    virtual void writeDataAsFragment(std::ostream & output);
    virtual void setElementData(std::string elementName, std::string elemen$

    virtual void move(int dir, DungeonLevel & dl);

    virtual void setXLoc(int xToSet);
    virtual int getXLoc();
    virtual void setYLoc(int yToSet);
    virtual int getYLoc();

    virtual int getLevel();
    virtual void setLevel(int levelToSet);
    virtual int getHP();
    virtual void setHP(int HPToSet);
    virtual int getMaxHP();
    virtual void setMaxHP(int maxHPToSet);

private:
    int xLoc;
    int yLoc;
    int level;
    int HP;
    int maxHP;

    // Not worried about inventory yet...
    //std::vector<Item*> m_vInventory;

};

生物.cpp

#include "Creature.h"
#include <cstdlib>
#include "DungeonLevel.h"

using namespace std;

Creature::Creature(void){
    HP = 0;
    maxHP = 0;
    level = 0;
}


Creature::~Creature(void){

}

void Creature::move(int dir, DungeonLevel & dl){
    //If I take the DungeonLevel & dl param. out.. I don't get errors
}

void Creature::dumpObject(){
    cout << "Creature:" << endl;
    dumpObjectData();
}
//The rest shouldn't be needed

瓷砖.h

#include "Creature.h"
#include "Item.h"

#include <vector>

class Tile : public Entity {
public:
    Tile(void);
    Tile(char ch);
    virtual ~Tile(void);
    void setCreature(Creature * creatureToSet);
    Creature * getCreature();
    void setDisplayChar(char displayCharToSet);
    char getDisplayChar();

private:
    char displayChar;
    Creature * theCreature;
    std::vector<Item*> inventory;
};

瓷砖.cpp

#include "Tile.h"
#include "Entity.h"

using namespace std;

Tile::Tile(void){
    displayChar = ' ';
    theCreature = NULL;

}

Tile::Tile(char ch) {
    setDisplayChar(ch);
    theCreature = NULL;
}

Tile::~Tile(void){

}

void Tile::setDisplayChar(char displayCharToSet){
    displayChar = displayCharToSet;
}

char Tile::getDisplayChar(){

    if ( theCreature != NULL ){
            return theCreature->getDisplayChar();
    }
    else {
            return displayChar;
    }
}

void Tile::setCreature(Creature * creatureToSet){
    theCreature = creatureToSet;
}

Creature * Tile::getCreature(){
    return theCreature;
}

播放器.h

#include "Creature.h"
#include "Weapon.h"
#include "Armor.h"
#include "DungeonLevel.h"

class Player : public Creature {

public:
    Player(void);
    virtual ~Player(void);

    virtual void dumpObject();
    virtual void dumpObjectData();
    virtual void writeFragment(std::ostream & output);
    virtual void writeDataAsFragment(std::ostream & output);
    virtual void setElementData(std::string elementName, std::string elemen$


    virtual int getScore();
    virtual void setScore(int scoreToSet);
    virtual int getXp();
    virtual void setXp(int xpToSet);

    virtual void setPlayerWeapon(Weapon* playerWeaponToSet);
    virtual Weapon* getPlayerWeapon();
    virtual void setPlayerArmor(Armor* playerArmorToSet);
    virtual Armor* getPlayerArmor();

private:
    //Creature provides level, HP, and maxHP
    int score;
    int xp;
    Weapon * playerWeapon;
    Armor * playerArmor;
};

播放器.cpp

#include "Player.h"
#include "Creature.h"

#include <cstdlib>

using namespace std;

Player::Player(void){
    setMaxHP(25);
    setHP(getMaxHP());
    setLevel(1);
    setDisplayChar('o');
    score = 0;
    xp = 0;
}


Player::~Player(void){

}
//the rest shouldn't be needed

请帮助我,谢谢!让我知道是否需要提供更多。谢谢!

4

2 回答 2

2

您的包含中有循环依赖项。DungeonLevel.h 包含 Player.h,反之亦然。由于包含守卫的性质,一个总是在另一个之前,但是顺序可以通过小的变化来交换。

您必须删除循环依赖项。

于 2013-04-14T04:02:51.710 回答
1

添加到@pubby 所写的内容。您应该为所有文件添加包含保护。避免循环依赖问题。

#ifndef _FILENAME_H_

#define _FILENAME_H_

// 文件中的所有内容都放在这里

#endif // _FILENAME_H_

其中 _FILENAME_H_ 是我们的头文件的名称。即使您有循环依赖,这也将确保所有内容都只会包含一次。但是,当您需要在其他内容之前包含某些内容时,循环依赖可能会导致其他问题。因此,应尽可能避免循环依赖。

于 2013-04-14T04:10:52.503 回答