-1

I have a class called MapGraph and another class called GameState. I'm calling two functions called GoToLocation(NextLocation); and Game->SidePanel(); from main. GoToLocation() declaration and definition exist in MapGraph.h and MapGraph.cpp respectively and SidePanel() declaration and definition exist in GameState.h and GameState.cpp respectively. In SidePanel() I'm trying to get the value of a variable called CurrentLocation that exists in MapGraph and is public. I've included MapGraph.h in GameState.cpp and declared the class as class MapGraph; but I don't know how to get the value of the variable. If I do MapGraph* Map = new MapGraph; that always gives me the initial value of the variable and not the updated one. Any help would be appreciated. Thank you.

The code in main.cpp:

int main()
{
    MapGraph* Map = new MapGraph;
    GameState* Game = new GameState;
    //Game->MainMenu();

    Map->GoToLocation(MapGraph::LocationNames::CastleSquare);
    Game->SidePanel();

    //system("CLS");
    return 0;
}

MapGraph.h:

#pragma once

#include <iostream>
#include <list>
#include <string.h>

class MapGraph
{
public:
    MapGraph();

    enum class LocationNames
    {
        GraveYard = 0,
        Sewers = 1,
        Outskirts = 2,
        Barracks = 3,
        Town = 4,
        CastleSquare = 5,
        ThroneRoom = 6,
        Forest = 7,
        Gutter = 8,
        HunterShack = 9
    };

    std::string LocNamesString[10] =
    {
        "Grave Yard",
        "Sewers",
        "Outskirts",
        "Barracks",
        "Town",
        "Castle Square",
        "Throne Room",
        "Forest",
        "Gutter",
        "Hunter Shack"
    };

    LocationNames CurrentLocation;
    void GoToLocation(LocationNames NextLocation);
};

and GameState.cpp:

#include <iostream>
#include <stdlib.h>
#include "GameState.h"
#include "MapGraph.h"

class MapGraph;

void GameState::SidePanel()
{
    MapGraph* Map = new MapGraph;

    std::cout << Map->LocNamesString[(int)Map->CurrentLocation];
}

P.S.: I tried changing CurrentLocation in MapGraph.h to static but that always generates a linker error 2001. The error goes aways as soon as i remove the word static.

Thank you.

walnut
  • 21,629
  • 4
  • 23
  • 59
Tsubaki13
  • 231
  • 1
  • 2
  • 4
  • 1
    You leak all your dynamic allocations. – eerorika Nov 08 '19 at 20:29
  • You apparently created two completely independent objects that have no relationship, whatsoever, with each other. This makes it logically impossible for any one of these objects to have any idea about anything related to the other object. Creating a 2nd, duplicate copy of the same object doesn't change that. Sorry, C++ does not work this way. – Sam Varshavchik Nov 08 '19 at 20:32
  • It is difficult to understand what you want to do. Is your intention to have only *one* instance of said variable? Because (if you didn't declare it `static`) each instance of a class has its own instances of member variables. I have a feeling you might not be understanding what class instances are or how they work. Please provide a complete [repro] to clarify. A linker error on `static` members is a common mistake to make, see e.g. [here](https://stackoverflow.com/questions/9110487/undefined-reference-to-a-static-member) – walnut Nov 08 '19 at 20:32
  • What `static`? I don't see it in your example. –  Nov 08 '19 at 20:33
  • If you do want to have multiple instances of the variable, but only one per `GameState`, then `GameState` should have a member of type `MapGraph`. You are also including the wrong standard library header here: `#include `. What you mean (in order to use `std::string`) is `#include` which is a *different* header. Forward declaring `class MapGraph;` as you do, after already having included the correct header with the full definition is also redundant and potentially source of future bugs if you accidentally remove the header include. Finally, don't use `new` (mostly). – walnut Nov 08 '19 at 20:37
  • Whenever you are thinking of using dynamic memory allocation (i.e. `new`), first ask yourself whether a normal variable will also do the job and if not whether a `std::vector` or `std::unique_ptr` or `std::shared_ptr` will. – walnut Nov 08 '19 at 20:43
  • Hey guys. Sorry if my question was confusing or unclear. I'm quite new to programming and I've been scratching my head over this for 2 days. I want CurrentLocation to be static but whenever i add the word `static` in front of it i get a linker error. Also, i don't know how to read a variable from another class. SidePanel() is a function in GameState that is supposed to read the name of the current location which is a member variable of MapGraph and print it out. Thank you @uneven_mark for the tips. I changed string.h to string. – Tsubaki13 Nov 08 '19 at 21:46
  • I don't really want to use new because i don't want to create new instances but i don't know how to have a reference to the class without creating a new instance of it, however, creating a new instance with new doesn't give me the current value of the variable. I hope i'm making myself clear. – Tsubaki13 Nov 08 '19 at 21:47
  • @Tsubaki13 For the error on `static`, I linked you to one (of many) questions answering that issue. Does it resolve your problem? You access static member variables with the scope resolution operator `::`, e.g. `MapGraph::CurrentLocation`. You access non-static member variables by the member access operator `.` applied to an instance of the class, which again I am not sure you fully understand the concept of. – walnut Nov 08 '19 at 21:49
  • @Tsubaki13 `new` does not mean `create new instance`. While `new` does create an instance, it has an additional effect relating to memory management and if you are new to programming (in C++), you should not have learned about it yet. It is rarely needed and an advanced topic. If you saw `new` used a lot, it was either in bad C++ code or e.g. Java, where it has a different meaning. Are you following some introductory book to C++? – walnut Nov 08 '19 at 21:51
  • I'm taking a c++ course at university and i have to create a text adventure game and i can't figure out how to get variable values from different classes. – Tsubaki13 Nov 08 '19 at 22:12
  • When i add the word static in from of CurrentLocation and compile, it immediately gives me the linker error before i even try to access it from anywhere. I've read in one of the forums that i should initialize the static variable in the cpp file but i can't seem to quite grasp how to do that neither. I tried `MapGraph::LocationNames MapGraph::CurrentLocation = MapGraph::LocationNames::GraveYard;` in the cpp file and it compiled, but now i get the same error again whenever i try to access it, for example: .`std::cout << LocNamesString[(int)CurrentLocation];` – Tsubaki13 Nov 08 '19 at 22:18
  • Problem solved.. Somehow. Thank you for the help :) – Tsubaki13 Nov 08 '19 at 23:03

1 Answers1

0

There are several ways to design this relationship. It's up to you to decide which fits best with your overall design. (One big question would be how many MapGraph objects do you expect to exist at the same time?) The simplest approach might be to pass the needed variable as a parameter.

void GameState::SidePanel(cosnt MapGraph & Map)
{
    std::cout << Map.LocNamesString[(int)Map.CurrentLocation];
}

Still, I would go a bit further and incorporate this line of logic into the MapGraph class. In that case, your function becomes

void GameState::SidePanel(cosnt MapGraph & Map)
{
    std::cout << Map.CurrentLocationName();
}

and the following gets added to the MapGraph definition

class MapGraph {
    // Existing stuff here

public:
    std::string CurrentLocationName()
    {
        return LocNamesString[(int)CurrentLocation];
    }

    // Possibly more definitions here
};

As a general rule, only your MapGraph implementation should need to know how MapGraph data is stored. When other code needs a combination of MapGraph data (such as getting the current location converted to a string), the MapGraph class should provide an interface for that.

By the way, LocNamesString should probably be static and const. The static keyword says that the name strings do not vary from MapGraph object to MapGraph object. The const keyword says that the name strings are not changed after initialization.

JaMiT
  • 14,422
  • 4
  • 15
  • 31