0

So I've been putting a lot of my variables (i.e. strings, ints, chars etc) into my header files for all my classes that I am creating. What I have noticed today is that by doing so I often get stackdumps when I try and access methods that use these variables. However if I remove the variable from the header file and place it directly into my cpp file it works a treat. Are we only supposed to use method declaration inside c++ header files? If not why would this be occurring (all the variables are private but are being accessed via set and get methods).

Thanks

In main.cpp:

GameManager gamemngr;

GameManager.h

#include <string>
#include "Location.h"
#ifndef GAMEMANAGER_H_
#define GAMEMANAGER_H_

class GameManager {
public:
    GameManager();
    Location* curLoc;
    std::string gethelpMenu();
    void movePlayer(int i);
private:
    Location one, two;
    std::string helpMenu;
    void initialiseLocations();
};

#endif /* GAMEMANAGER_H_ */

Location.h

#include <string>
#ifndef LOCATION_H_
#define LOCATION_H_

class Location {
public:
    Location();
    void setEdges(Location *n, Location *e, Location *s, Location *w);
    Location* getEdge(int i);
    void setDescription(std::string s);
    std::string getDescription();
private:
    Location* pathways[];
    bool blocked[4];
    bool locked[4];

};

#endif /* LOCATION_H_ */

If I add a std::string description; to the location header and then try and access it via curLoc->getDescription it just stack dumps as soon as it gets to that line in the program. I'm assuming my pointer is pointing to invalid memory but curLoc has the same memory address as the object "one". Am I incorrectly instantiating my objects or something?

EDIT: I will also add I do set it to a default value in the constructor to make sure the string is properly initialised but that has no effect.

Location Implementation (with description placed inside the header file as per my original implementation):

#include "Location.h"
#include <string>
#include <iostream>

Location::Location() {
    description = "";
    for (int i = 0; i < 4; i++) {
        pathways[i] = NULL;
        blocked[i] = false;
        locked[i] = false;
    }
}

void Location::setEdges(Location *n, Location *e, Location *s, Location *w) {
    pathways[0] = n;
    pathways[1] = e;
    pathways[2] = s;
    pathways[3] = w;
}

Location* Location::getEdge(int i) {
    if(pathways[i] == NULL) {
        return this;
    } else {
        return pathways[i];
    }
}

void Location::setDescription(std::string s) {
        description = s;
}

std::string Location::getDescription() {
    return description;
}

I should probably also add this only seems to be happening with my description string and not the edges methods I have defined as well, as far as I can tell they are working (I need the descriptions to double check my pointers location to be sure but it doesn't stackdump or throw errors).

Scott
  • 465
  • 3
  • 10
  • 22
  • 1
    Can you include an example of the problem you're experienced? – nhgrif Dec 05 '13 at 03:28
  • @nhgrif added some extra info if that helps. – Scott Dec 05 '13 at 03:35
  • if you mean "are we only supposed to put method declarations in .cpp files" then yes, you are. – Jules G.M. Dec 05 '13 at 03:53
  • http://stackoverflow.com/questions/18543980/symbol-not-found-when-using-template-defined-in-a-library/18544093#18544093 could be a good read, the linker SHOULD ONLY see one symbol with a certain name. You were confusing it because the header file defines a variable, everywhere that it is included ALSO defines that variable, so the linker saw loads of declarations from the compiled objects of every file that you included it in! – Alec Teal Dec 05 '13 at 04:04
  • Forward Declaration...Anyone? – Recker Dec 05 '13 at 04:05
  • So does the issue lie with WHERE I am declaring my method or the variable itself? I'm still getting my head around all these includes and header files and I clearly have something in the wrong place. I understand that it is as a result of having multiple objects with the same variable names but I don't quite understand where or how I rectify that. – Scott Dec 05 '13 at 04:12
  • Did you ever initialize curLoc? – user253751 Dec 05 '13 at 04:27
  • @immibis yes in my cpp file for GameManager I have `curLoc = @one;` – Scott Dec 05 '13 at 05:01
  • Where in the cpp file? Post that part. (Edit: As in, which function?) – user253751 Dec 05 '13 at 05:08
  • `GameManager::GameManager() {` `initialiseLocations();` `curLoc = &one;` `}` – Scott Dec 05 '13 at 05:33
  • It is in the constructor – Scott Dec 05 '13 at 06:55

1 Answers1

1

There is compiler behavior where if the compiler doesn't see your variables being used in a .cpp file, then it will cut the variables from the class, unless there is a clear compilation flag to tell it not to. You should always declare your methods in .cpp files.

Jules G.M.
  • 3,624
  • 1
  • 21
  • 35
  • "You should always declare your methods in .cpp files" -- Says who? – Shoe Dec 05 '13 at 04:00
  • @Jefffrey ".cxx" ftw, pluses are unstable! They fall over! Anyway, you need the compiler to see your methods. There's a one declaration rule. – Alec Teal Dec 05 '13 at 04:02
  • @Jefffrey http://stackoverflow.com/questions/18543980/symbol-not-found-when-using-template-defined-in-a-library/18544093#18544093 that should explain linking a bit more to you. EVERYTHING must only be found one (unless it has weak linkage) – Alec Teal Dec 05 '13 at 04:03
  • ... or disable this optimization I suppose – Jules G.M. Dec 05 '13 at 04:06
  • I know about linking and I know about ODR. What I don't know is who said that you should *always* *declare* your methods (I think you meant member functions) in `.cpp` files (source files). – Shoe Dec 05 '13 at 04:42
  • The member function **declaration** is generally found in `.hpp` or `.h` (header) files. The member function **definition** is usually found in `.cpp` (the extension doesn't really matter) or source files. That doesn't mean you should **always** do this. There might be cases when you want to **define** something in header files (header only libraries for example, or template classes) and you can do that. Don't make up rules that aren't there. – Shoe Dec 05 '13 at 04:44