0

My Ifndef isn't working. I have MapData.h included twice in both: Generate.cpp and Risky Strats.cpp

MapData.h:

#ifndef MAPDATA
#define MAPDATA
#include <iostream>
#include <vector>
class bases {
public:
    int x;
    int y;
};

class field {
public:
    std::vector <bases> map;
};
field battleground;
#endif //MAPDATA

Generate.cpp:

#include <stdlib.h>//Randomness
#include <time.h>//time
#include <math.h>
#include "MapData.h"

Risky Strats.cpp:

#include <SFML/Graphics.hpp>
#include "MapData.h"

I keep getting the same error: class field battleground" (?battleground@@3Vfield@@A) already defined in Generate.obj

Random Guy
  • 61
  • 7
  • 3
    ...and what is the problem? – M.M Mar 30 '20 at 04:28
  • The `ifndef` is working properly, as your error is a *linker* error, not a compile error. You misunderstand what the purpose of this construct is. It is to ensure that for *each* module that's compiled, the code in the include file is seen once. – PaulMcKenzie Mar 30 '20 at 05:17
  • 1
    Does this answer your question? [Why error LINK2005: object already defined error disappears when I declare the object as static](https://stackoverflow.com/questions/4182866/why-error-link2005-object-already-defined-error-disappears-when-i-declare-the-o) Also see the answers to [One or more multiply defined symbols found](https://stackoverflow.com/questions/6469849/one-or-more-multiply-defined-symbols-found), which address the same underlying misconception, just with a function as the symptom instead of a variable. – JaMiT Mar 30 '20 at 06:55

2 Answers2

2

The "dance of the ifdefs" stops you including the same .h multiple times in one .cpp. You only include it once per .cpp file, but you include it in two different .cpp files which means both of those .cpp files have the global variable battleground.

You could extern the variable declaration in the .h and put the definition into one of the .cpp files (or MapData.cpp) but I'd start by questioning whether having a global variable is the right design choice in the first place.

John3136
  • 28,809
  • 4
  • 51
  • 69
2

That's not how include guards work - they prevent against multiple inclusion of the same header file in a single translation unit, not across multiple translation units.

As you have it now, each of your translation units gets a global object called battleground, and then there's a collision at link time.

If in fact you want a single global field battleground, you need to add extern to field battleground; in your header, then take the definition field battleground; and put it in exactly one of your .cpp files.

Carl Norum
  • 219,201
  • 40
  • 422
  • 469