0

我正在尝试为基于代理的僵尸启示录模拟编译几个文件(太棒了,对吧!?)无论如何,我收到一个错误,我认为这与包含头文件的顺序有关,但我我不知道如何弄清楚出了什么问题以及如何解决它。确切的错误是:“在 main.cpp 包含的文件中,‘位置’字段的类型不完整。” 然后类似地,“在构造函数 Creature::Creature() 'Location' 中未声明”。

这是我的文件:

定义.h

#ifndef definitions_h
#define definitions_h
class Creature;
class Item;
class Coords;

class Grid
{

public:
      Creature*** cboard;
      Item*** iboard;

      Grid(int WIDTH, int HEIGHT);
      void FillGrid(int H, int Z); //initializes grid object with humans and zombies  
      void Refresh(); //calls Creature::Die(),Move(),Attack(),Breed() on every square
      void UpdateBuffer(char** buffer);
      bool isEmpty(int startx, int starty, int dir);

};

class Random
{
    public:
        int* rptr;
        void Print();
        Random(int MIN, int MAX, int LEN);
        ~Random();
    private:
        bool alreadyused(int checkthis, int len, int* rptr);
        bool isClean();
        int len;
};

class Creature
{

public:
      bool alive;
      Coords Location;
      char displayletter;

      Creature() {Location.x=0; Location.y=0;} //ERROR HERE
      Creature(int i, int j) {Location.xvalue(i); Location.yvalue(j);} 

      virtual void Attack();
      virtual void Breed();
      virtual void Move(Creature*** cboard);
      virtual void Die();

      virtual void MoveTo(Creature*** cboard, int dir); 
      virtual int DecideSquare(Creature*** cboard); 
};

class Human : public Creature 
{
public:      
      bool armed; //if armed, chances of winning fight increased for next fight 
      bool vaccinated; //if vaccinated, no chance of getting infected

      int bitecount; //if a human is bitten, bite count is set to a random number
      int breedcount; //if a human goes x steps without combat, will breed if next to a human
      int starvecount; //if a human does not eat in x steps, will die 

      void Attack(Creature*** cboard);
      void Breed(Creature*** cboard); //will breed after x steps and next to human
      void Move(Creature*** cboard); //moves and checks itemboard for food
      void Die(); //depends on bitecount, starvecount, and bool alive

      void MoveTo(Creature*** cboard, int dir);
      int DecideSquare(Creature*** cboard) {Creature::DecideSquare(Creature*** cboard);}

};

class Zombie : public Creature
{
   public:
      Zombie(int i, int j) {Creature::Creature()};
      void Attack(Creature*** cboard); //will attack any adjacent human
      void Breed() {} //does nothing
      void Move(Creature*** cboard) {Creature::Move(Creature*** cboard;}
      void Die(); //can only die from being attacked, never starves


};

class Item
{

};

class Coords
{
  public:   
      int x;
      int y;
      int MaxX;
      int MaxY;

      Coords() {x=0; y=0; MaxX=0; MaxY=0;}
      Coords(int X, int Y, int WIDTH, int HEIGHT) {x=X; y=Y; MaxX=WIDTH; MaxY=HEIGHT; }

      void MoveRight();
      void MoveLeft();
      void MoveUp();
      void MoveDown();
      void MoveUpRight();
      void MoveUpLeft();
      void MoveDownRight();
      void MoveDownLeft();
      void MoveDir(int dir);
      void setx(int X) {x=X;}
      void sety(int Y) {y=Y;}
};

#endif

主文件

#include <cstdlib>
#include <iostream>
#include "definitions.h"

using namespace std;

int main(int argc, char *argv[])
{
    system("PAUSE");
    return EXIT_SUCCESS;
}

定义.cpp

#include <cstdlib>
#include "definitions.h"

Grid::Grid(int WIDTH, int HEIGHT)
{
     //builds 2d array of creature pointers
     cboard = new Creature**[WIDTH];
     for(int i=0; i<WIDTH; i++)
     {
             cboard[i] = new Creature*[HEIGHT];
     }

     //builds 2d array of item pointers
     iboard = new Item**[WIDTH];
     for (int i=0; i<WIDTH; i++)
     {
              iboard[i] = new Item*[HEIGHT];
     }
}

void Grid::FillGrid()
{
     /* For each creature pointer in grid, randomly selects whether to initalize
     as zombie, human, or empty square. This methodology can be changed to initialize
     different creature types with different probabilities */

     int random;

     for (int i=0; i<WIDTH; i++)
     {
         for (int j=0; j<HEIGHT; j++)
         {
             Random X(1,100,1); //create a single random integer from [1,100] at X.rptr
             random=X->rptr;
             if (random < 20)
                cboard[i][j] = new Human(i,j);
             else if (random < 40) 
                  cboard[i][j] = new Zombie(i,j); 
             else 
                  cboard[i][j] = NULL;
         }
     } //at this point every creature pointer should be pointing to either
     //a zombie, human, or NULL with varying probabilities 

}

void Grid::UpdateBuffer(char** buffer)
{
     for (int i=0; i<WIDTH; i++)
     {
         for (int j=0; j<HEIGHT; j++)
         {
             if (cboard[i][j])
                buffer[i][j]=cboard[i][j]->displayletter;
             else
                 buffer[i][j]=' ';
         }
     }

}

bool Grid::isEmpty(int startx, int starty, int dir)
{
     Coords StartLocation(startx,starty,WIDTH,HEIGHT);
     switch(dir)
     {
                case 1:
                     StartLocation.MoveUp();
                      if (cboard[StartLocation.x][StartLocation.y])
                        return 0;
                case 2:
                     StartLocation.MoveUpRight();
                      if (cboard[StartLocation.x][StartLocation.y])
                        return 0;
                case 3:
                     StartLocation.MoveRight();
                      if (cboard[StartLocation.x][StartLocation.y])
                        return 0;
                case 4:
                     StartLocation.MoveDownRight();
                      if (cboard[StartLocation.x][StartLocation.y])
                        return 0;
                case 5:
                     StartLocation.MoveDown();
                      if (cboard[StartLocation.x][StartLocation.y])
                        return 0;
                case 6:
                     StartLocation.MoveDownLeft();
                      if (cboard[StartLocation.x][StartLocation.y])
                        return 0;
                case 7:
                     StartLocation.MoveLeft();
                      if (cboard[StartLocation.x][StartLocation.y])
                        return 0;
                case 8:
                     StartLocation.MoveUpLeft();
                      if (cboard[StartLocation.x][StartLocation.y])
                        return 0; 
     }
     return 1;
}


void Coords::MoveRight() {(x==MaxX)? (x=0):(x++);}
void Coords::MoveLeft() {(x==0)? (x=MaxX):(x--);}
void Coords::MoveUp() {(y==0)? (y=MaxY):(y--);}
void Coords::MoveDown() {(y==MaxY)? (y=0):(y++);} 
void Coords::MoveUpRight() {MoveUp(); MoveRight();}
void Coords::MoveUpLeft() {MoveUp(); MoveLeft();}
void Coords::MoveDownRight() {MoveDown(); MoveRight();}
void Coords::MoveDownLeft() {MoveDown(); MoveLeft();}
void Coords::MoveDir(int dir)
{
     switch(dir)
     {
                case 1:
                     MoveUp();
                     break;
                case 2:
                     MoveUpRight();
                     break;
                case 3:
                     MoveRight();
                     break;
                case 4:
                     MoveDownRight();
                     break;
                case 5:
                     MoveDown();
                     break;
                case 6:
                     MoveDownLeft();
                     break;
                case 7:
                     MoveLeft();
                     break;
                case 8:
                     MoveUpLeft();
                     break;
                case 0:
                     break;
     }
}
4

2 回答 2

2

您的class Coordsin前向声明definitions.h不足以声明 type 的变量Coords

前向声明引入了类型,但不完整。您可以使用指向不完整类型的指针声明变量,但不能声明具有不完整类型的变量。因此,您必须将 的定义移到 的定义class Coords之前class Creature

如果你发现自己有循环声明依赖,你必须引入一个指针或引用声明器来解决它。

于 2012-11-23T18:12:13.343 回答
1

声明变量时,必须知道其类型。在您的情况下,这意味着Coords必须在声明中使用它的定义Coords Location;

从编译器的角度来看:它需要知道将占用多少空间Location,为此它需要知道Coords. 当然,它是从上到下解析的。

于 2012-11-23T18:07:24.853 回答