2012-11-23 33 views
0

我想一起編譯幾個文件一起基於殭屍啓示錄的模擬仿真(真棒,正確!?)無論如何,我得到一個錯誤,我認爲必須做包含頭文件的順序,但是我無法將頭圍繞如何弄清楚什麼是錯誤的以及如何解決它。確切的錯誤是:「在main.cpp中包含的文件中,」位置「字段的類型不完整。」然後類似地,「在構造器Creature :: Creature()'位置'未聲明的」。字段有不完整的類型,從多個文件編譯

這裏是我的文件:

definitions.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 

的main.cpp

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

using namespace std; 

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

definitions.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; 
    } 
} 

回答

1

當聲明一個變量,其類型必須是已知的。在你的情況下,這意味着Coords的定義必須先於其在聲明Coords Location;中的使用。

從編譯器的角度來看它:它需要知道需要多少空間Location,爲此它需要知道Coords的定義。當然,它是從上到下的解析。

2

您在definitions.h中的class Coords的前向聲明不足以聲明類型爲Coords的變量。

前向聲明引入了類型,但不完整。您可以使用指向不完整類型的指針來聲明變量,但不能使用不完整類型的變量。因此,您必須在class Creature的定義之前移動class Coords的定義。

如果您發現自己具有循環聲明依賴項,則必須引入一個指針或引用聲明符來解決它。

相關問題