簡體   English   中英

#include文件不包含(c ++)

[英]#include files not including (c++)

我在使用C ++中的#include文件時遇到問題。 當我嘗試編譯以下代碼時

#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);}
};

我收到未定義“容器”和“事物”的錯誤消息。 為什么是這樣? #include在我看來就像是正確編碼的,並且它們在過去已經工作過。 我認為這可能是#include的文件未正確地用括號括起來或未使用相同的名稱空間的問題,但它們正確地以(;;結束),並且它們使用的是標准名稱空間。 這是怎么回事? 我找不到答案,我知道這一定很簡單。 作為記錄,#include的文件如下:

    #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

我相信這是因為您具有遞歸依賴性。 也就是說,您的類都相互依賴,這意味着某個類將無法編譯,因為要進行編譯,將需要聲明一個類,但無法進行聲明。找到聲明,因為它位於頭文件中的“ #include”堆棧中,並且由於保護而使“ #ifdef”為空。

舉個例子。 要編譯Tile ,您需要聲明Location ,因此,自然地,您#include "location.h" 但是,要編譯Location聲明,則需要Tile聲明,因此,您需要#include "Tile.h" 但是Tile.h 已經#include -ed了,所以沒有聲明!

解決此類循環依賴關系的方法是使用不完整的類聲明。 例如,不要將location.h包含在Tile.h中,而是編寫

class Location;

class Tile
{
    Location* loc;
}

只要Location僅用於聲明指針或引用並且不訪問Location類的成員,此方法就起作用。

然后,在您的“ Tile.c”文件中,您可以#include "location.h"並允許您對Tile方法的擴展訪問Location成員。

您有一個包含循環

  • 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.hThingContainer是未知的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM