2013-05-28 2 views
-1

У меня возникла проблема с #include файлами в C++. Когда я пытаюсь скомпилировать следующий код# включить файлы, не включенные (C++)

#ifndef TILE_H_INCLUDED 
#define TILE_H_INCLUDED 
#include "location.h" 
#include "Thing.h" 
#include "Container.h" 
#include <string> 
using namespace std; 

class Tile    //VIRTUAL CLASS 
{ 
protected: 
    Container onTile; //holds objects that are on the tile 
    Location * loc;  //location 
    Tile* N;   //links to Tiles of that direction (null if nothing) 
    Tile* E; 
    Tile* S; 
    Tile* W; 
public: 
//no constructor because superclass? 
//loc can't move 
//actions 
bool placeOnTile(Thing * i){return onTile.addItem(i);} 
    //put a thing on the tile (on the floor) 
Thing* takeFrmTile(int i){return onTile.movItem(i);} 
    //take a thing from the tile (from the floor) 
Thing* access(int i) {return onTile.getItem(i);} 
    //gets an item, but doesn't move it (for like, flipping switches) 

//direction setters/getters 
void setLoc(Location* i){loc = i;} 
void setN(Tile* i){N = i;} 
void setE(Tile* i){E = i;} 
void setS(Tile* i){S = i;} 
void setW(Tile* i){W = i;} 
Location* getLoc(){return loc;} 
Tile* getN(){return N;} 
Tile* getE(){return E;} 
Tile* getS(){return S;} 
Tile* getW(){return W;} 

//displays 
void dispOnTile(){onTile.allDisplay();} 
void dispSingle(int i){onTile.singleDisplay(i);} 
}; 

Я получаю сообщение об ошибке, «Контейнер» и «Вещь» не определены. Почему это? #includes выглядят так, как будто они правильно закодированы, и они работали в прошлом. Я предположил, что это может быть проблема с # включенными файлами, которые не являются конечными скобками правильно или не используют одно и то же пространство имен, но они закончены правильно (с помощью;); они используют стандартное пространство имен. Что происходит? Я не могу найти ответ, и я знаю, что это должно быть что-то простое. Для записи, то #included файлы ниже:

#ifndef CONTAINER_H_INCLUDED 
#define CONTAINER_H_INCLUDED 
#include "Thing.h" 
using namespace std; 

class Container 
{ 
private: 
    Thing ** contents; //array of pointers to Things 
    int numItems;  //count item 
    int maxSize;  //maxSize 

public: 
    //constructor 
    Container(int i) {contents = new Thing*[i]; numItems = 0; maxSize=i;} 
     //sets num of items (for set-size bags) 
    Container() {contents = new Thing*[100]; numItems = 0; maxSize=100;} 
     //creates array of things 
    ~Container() {delete contents;} //cleanup 

//actions 
bool addItem(Thing* th); //adds item to bag (really just rereferences the pointer) 
bool rmvItem(int i);  //removes item in array pos i 
Thing* getItem(int i);  //returns a pointer to item at array pos i 
Thing* movItem(int i);  //moves an item (deletes it and returns it) 

//construction tools 
void setMax(int i){delete contents; contents = new Thing*[i];} 

//displays 
void allDisplay();   //displays entire contents of container, numerated 
void singleDisplay(int i); //displays content item i 

}; 

#endif // CONTAINER_H_INCLUDED 

    #ifndef LOCATION_H_INCLUDED 
#define LOCATION_H_INCLUDED 
#include <string> 
#include <sstream> 
#include "Tile.h" 
using namespace std; 

class Location //stores xy coordinates of something 
{ 
int x; //0 is NOT on map 
int y; 
Tile* ti; //Locations contain pointers to tiles 
public: 
//constructors (mainly for debug) 
Location(){x=y=0;} //put object OUT OF MAP 
Location(int ix, int iy){x=ix;y=iy;} //put object AT loc on map 

//setters 
void setX(int ix){x=ix;} //sets x 
void setY(int iy){y=iy;} //sets y 
void setT(Tile*i){ti=i;} //sets Tile 

//getters 
int getX() {return x;} 
int getY() {return y;} 
string getloc()  //return location as a string, separated by a comma 
{ 
    ostringstream locxy; //create stringstream obj to handle input 
    locxy << getX() << "," << getY() << ". "; //put x, space, y into stringstream 
    string locret = locxy.str();  //convert stringstream to string 
    return locret;      //return string 
    } 
}; 

#endif // LOCATION_H_INCLUDED 


    #ifndef THING_H_INCLUDED 
#define THING_H_INCLUDED 
#include <string> 
#include "location.h" 
using namespace std; 

class Thing    //superclass that will be the base for objects 
{ 
protected: 
    Location * loc;  //location (in or out of map) 
    string name;  //name 
    string desc;  //description 
    bool deletable;  //deletable (for undestructible items) 
    bool takeable;  //if you can put it in your inv 
    bool hasInv;  //returns true if the item has an inventory 
public: 
//constructor/destructor (debug only) 
Thing() //sets initial values 
    {loc = new Location(0, 0); 
    name = "Uninitialized"; 
    deletable = takeable = true; 
    } 
Thing(int ix, int iy) //sets location 
    {loc = new Location(ix, iy); 
    name = "Uninitialized"; 
    deletable = takeable = false;} 
~Thing() {delete loc;}    //deletes allocated data 

//getters 
Location* getLoc() {return loc;} //returns the location 
string getDesc(){return desc;}  //returns the description 
bool getDel(){return deletable;} //returns deletable status 
bool getTake(){return takeable;} //returns takeable status 
string getName(){return name;}  //returns name 
string dispLoc(){return loc->getloc();} //displays location 

//setters 
void setName(string s){name = s;} //sets name 
void setDel(bool b){deletable = b;} //sets deletability 
void setDesc(string d) {desc = d;} //sets desc 
void setLoc(Location* l) {loc = l;} //sets loc 
void setTake(bool b){takeable = b;} //sets takeability 

//accessors 
}; 

#endif // THING_H_INCLUDED 
+0

Проверьте, не пропустили ли вы ';' в любом месте. Не пишите 'using namespace std;' в файле заголовка. Он загрязняет область действия, если таковые имеются, включая заголовки. – Mahesh

+0

Я не думаю, что мне не хватает никого; в коде. Разве это не спровоцировало бы определенную ошибку компилятора? Я просто получаю целую кучу ошибок, все связанные с тем, что, по-видимому, не определены классы (много «CLASSNAME не называет класс») – ndantedouglas

+0

У вас несколько [круговых зависимостей] (http: // ru. wikipedia.org/wiki/Circular_dependency#Example_of_circular_dependencies_in_C.2B.2B) в вашем коде. –

ответ

1

У вас есть включаемый цикл

  • Tile.h включает

    1. location.h
    2. Thing.h
    3. Container.h
  • Container.h включает в себя Thing.h

  • Thing.h включает в себя location.h

  • location.h включает в себя Tile.h

К сожалению.

Итак, скажем, в .cpp, первый, который будет включен, - Container.h. Затем он включает в себя Thing.h, прежде чем он что-то объявит. Thing.h в свою очередь включает в себя location.h, прежде чем он объявит что-либо. Затем это включает Tile.h, прежде чем он что-то объявит. В Tile.h все включенные охранники делают рекурсивные объекты без операций.

И, следовательно, в Tile.h, Thing и Container неизвестны.

+0

Спасибо! Я думаю, что это моя ошибка. Я буду переоценивать код и пытаюсь это исправить. – ndantedouglas

2

Я считаю, что это потому, что у вас есть рекурсивные зависимости. То есть ваши классы все зависят друг от друга, а это означает, что в какой-то момент один из классов не сможет скомпилировать, потому что для того, чтобы скомпилировать его, потребуется объявление класса, но он не сможет найти объявление, потому что он находится в файле заголовка, который уже находится в стеке «#include» и, следовательно, из-за того, что «#ifdef» хранится, становится пустым.

Чтобы привести пример. Чтобы скомпилировать Tile, вам нужно объявление Location, так что, естественно, вы #include "location.h". Но, чтобы скомпилировать объявление Location, вам нужно объявление Tile, так что вы #include "Tile.h". Но Tile.hимеет#include -ed уже, поэтому есть no декларация для этого!

Способ борьбы с такими круговыми зависимостями заключается в использовании неполной декларации класса. Например, вместо того, чтобы в том числе location.h в Tile.h, написать

class Location; 

class Tile 
{ 
    Location* loc; 
} 

Это работает до тех пор, как Location используется только объявить указатель или ссылку и ни один из членов Location класса доступ.

Затем в вашем файле Tile.c вы можете #include "location.h" и разрешить использование вами Tile методов доступа к Location пользователям.

Смежные вопросы