lundi 29 novembre 2021

Class not recognised when included in header file in C++ [closed]

I'm trying to create a basic text adventure game using C++. I'm declaring the classes I use in header files, then including them where needed. For some reason, one header file does not recognise one header file included in it, and is not recognised by my main program.

The header file that seems to be causing the problem is State.h (this represents the game state and related functions):

#ifndef TEXTADV_STATE_H
#define TEXTADV_STATE_H

#include "Room.h"
#include "GameObject.h"

class State {
    Room *currentRoom;
    Room *previousRoom;
public:
    explicit State(Room *startRoom);
    static std::list<GameObject> inventory;
    void goTo(Room *target);
    void goBack();
    void announceLoc() const;
    Room* getCurrentRoom() const;
    Room* getPrevRoom() const;
};


#endif //TEXTADV_STATE_H

State.h does not recognise the GameObject class, despite the header file being included. The same class is recognised without issue in another header file: Room.h.

GameObject.h:

#ifndef TEXTADV_STATE_H
#define TEXTADV_STATE_H

#include <iostream>

using std::string;

class GameObject{
    string s_name;
    string desc;
    string keyword;
public:
    /** constructor */
    GameObject(const string *_s_name, const string *_desc, const string *_keyword);

    string getName();
    string getDesc();
    string getKeyword();
};

#endif //TEXTADV_STATE_H

Room.h:

#ifndef TEXTADV_ROOM_H
#define TEXTADV_ROOM_H

#include <string>
#include <forward_list>
#include <list>
#include "GameObject.h"

using std::string;

/**
 * Represents a room (accessible location in the game).
 */
class Room {
    /**
     * Short name used as a header.
     */
    const string* name;
    /**
     * Full description of the room.
     */
    const string* description;
    /**
     * Pointer to room that is n/s/e/w of this one.
     */
    Room* north;
    Room* south;
    Room* east;
    Room* west;

public:
    /**
     * Constructs a new Room.
     * @param _name Name of the room.
     * @param _desc Description of the room.
     */
    Room(const string *_name, const string *_desc);

    /**
     * Removes a destroyed room from the global list if it's there.
     */
    ~Room();

    /**
     * Outputs the name and description of the room
     * in standard format.
     */
    void describe() const;

    /**
     * List storing all rooms that have been registered via addRoom().
     */
    static std::list<Room*> rooms;

    /**
     * list of game objects in room
     */
    static std::list<GameObject*> room_objs;
    static std::list<GameObject*>::iterator obj_it;

    /**
     * Creates a new Room with the given parameters and register it with the static list.
     * @param _name Name of the room.
     * @param _desc Description of the room.
     */
    static Room* addRoom(const string* _name, const string* _desc);
    static void addRoom(Room* room);

    static void addObj(GameObject* obj) {};


    Room* getNorth() const;
    Room* getSouth() const;
    Room* getEast() const;
    Room* getWest() const;
    void setNorth(Room* _north);
    void setSouth(Room* _north);
    void setEast(Room* _north);
    void setWest(Room* _north);

};

#endif //TEXTADV_ROOM_H

Finally, my main programme main.cpp does not recognise the State.h file either. It previously did and I'm not sure what's changed (to my knowledge I haven't changed anything in either file that would change the relation/include) for this to happen.

main.cpp:

#include <iostream>
#include <iomanip>
#include <memory>
#include <iterator>
#include <vector>
#include <forward_list>
#include "Room.h"
#include "wordwrap.h"
#include "State.h"
#include "strings.h"
#include "GameObject.h"


using std::string;
using std::unique_ptr;

string commandBuffer;

State *currentState;

/**
 * Print out the command prompt then read a command into the provided string buffer.
 * @param buffer Pointer to the string buffer to use.
 */
void inputCommand(string *buffer) {
    buffer->clear();
    std::cout << "> ";
    std::getline(std::cin, *buffer);
}

/**
 * Sets up the map.
 */
void initRooms() {
    auto * r2 = new Room(&r2name, &r2desc);
    auto * r1 = new Room(&r1name, &r1desc);
    auto * r3 = new Room(&r3name, &r3desc);
    auto * r4 = new Room(&r4name, &r4desc);
    auto * r5 = new Room(&r5name, &r5desc);
    auto * obj1 = new GameObject(&obj1name, &obj1desc, &obj1keyw);
    Room::addObj(obj1);
    Room::addRoom(r1);
    Room::addRoom(r2);
    Room::addRoom(r3);
    r1->setNorth(r2);
    r1->setSouth(r3);
    r1->setEast(r4);
    r1->setWest(r5);


}

/**
 * Sets up the game state.
 */
void initState() {
    currentState = new State(Room::rooms.front());
}


/**
 * The main game loop.
 */
void gameLoop() {
    bool gameOver=false;
    while (!gameOver) {
        /* Ask for a command. */
        bool commandOk = false;
        inputCommand(&commandBuffer);

        /* The first word of a command would normally be the verb. The first word is the text before the first
         * space, or if there is no space, the whole string. */
        auto endOfVerb = static_cast<uint8_t>(commandBuffer.find(' '));

        /* We could copy the verb to another string but there's no reason to, we'll just compare it in place. */
        /* Command to go north. */
        if ((commandBuffer.compare(0,endOfVerb,"north") == 0) || (commandBuffer.compare(0,endOfVerb,"n") == 0)) {
            commandOk = true; /* Confirm command has been handled */
            /* See if there's a north exit */
            Room *northRoom = currentState->getCurrentRoom()->getNorth();
            if (northRoom == nullptr) { /* there isn't */
                wrapOut(&badExit);      /* Output the "can't go there" message */
                wrapEndPara();
            } else {                    /* There is */
                currentState->goTo(northRoom); /* Update state to that room - this will also describe it */
            }
        }
        if ((commandBuffer.compare(0,endOfVerb,"south") == 0) || (commandBuffer.compare(0,endOfVerb,"s") == 0)) {
            commandOk = true; /* Confirm command has been handled */
            /* See if there's a south exit */
            Room *southRoom = currentState->getCurrentRoom()->getSouth();
            if (southRoom == nullptr) { /* there isn't */
                wrapOut(&badExit);      /* Output the "can't go there" message */
                wrapEndPara();
            } else {                    /* There is */
                currentState->goTo(southRoom); /* Update state to that room - this will also describe it */
            }
        }
        if ((commandBuffer.compare(0,endOfVerb,"east") == 0) || (commandBuffer.compare(0,endOfVerb,"e") == 0)) {
            commandOk = true; /* Confirm command has been handled */
            /* See if there's a east exit */
            Room *eastRoom = currentState->getCurrentRoom()->getEast();
            if (eastRoom == nullptr) { /* there isn't */
                wrapOut(&badExit);      /* Output the "can't go there" message */
                wrapEndPara();
            } else {                    /* There is */
                currentState->goTo(eastRoom); /* Update state to that room - this will also describe it */
            }
        }
        if ((commandBuffer.compare(0,endOfVerb,"west") == 0) || (commandBuffer.compare(0,endOfVerb,"w") == 0)) {
            commandOk = true; /* Confirm command has been handled */
            /* See if there's a west exit */
            Room *westRoom = currentState->getCurrentRoom()->getWest();
            if (westRoom == nullptr) { /* there isn't */
                wrapOut(&badExit);      /* Output the "can't go there" message */
                wrapEndPara();
            } else {                    /* There is */
                currentState->goTo(westRoom); /* Update state to that room - this will also describe it */
            }
        }
        if ((commandBuffer.compare(0,endOfVerb,"back") == 0) || (commandBuffer.compare(0,endOfVerb,"b") == 0)) {
            commandOk = true; /* Confirm command has been handled */
            /* See if there's a previous room */
            Room *prevRoom = currentState->getPrevRoom();
            if (prevRoom == nullptr) { /* there isn't */
                wrapOut(&badExit);      /* Output the "can't go there" message */
                wrapEndPara();
            } else {                    /* There is */
                currentState->goBack(); /* Update state to that room - this will also describe it */
            }
        }

        /* Quit command */
        if ((commandBuffer.compare(0,endOfVerb,"quit") == 0)) {
            commandOk = true;
            gameOver = true;
        }

        /* If commandOk hasn't been set, command wasn't understood, display error message */
        if(!commandOk) {
            wrapOut(&badCommand);
            wrapEndPara();
        }
    }
}


int main() {
    initWordWrap();
    initRooms();
    initState();
    currentState->announceLoc();
    gameLoop();
    return 0;
}

I've tried using #ifndef #define but this does not solve the issue either. I've also tried recompiling and rebuilding but no joy there either. I'm absolutely stuck as to why State.h and GameObject.h are recognised in some files but not others. Any ideas?

Thank you.

Aucun commentaire:

Enregistrer un commentaire