Reputation: 3386
Well, I'm learning C++ and never really learned how to do stuff that is not OO. I'm trying to get a bit more experience coding in C style.
#pragma once
#ifndef GLOBALINFORMATION_H
#define GLOBALINFORMATION_H
#include "MapInformation.h"
namespace gi {
MapInformation mapInf;
};
#endif
I would like to be able to access gi::mapInf from every header and cpp in my project. Right now I'm including globalinformation.h in every header, so I'm getting linker errors with multiple definitions.
How can I work around the problem?
Upvotes: 20
Views: 28321
Reputation: 1854
Global variables are C, but namespaces are C++. There is a good discussion on using global variables and how they can be replaced by Singleton pattern: Globals and Singletons
And here is a simple sample: CPP/Classes/Singleton
Upvotes: 3
Reputation: 1721
Here are a few things that you need to take care of while trying to use global variables the way you have used.
Ensure that all the header files that the header files that GobalInformation.h includes are also enclosed insides #ifndefs. (I could not see mapinformation.h so I assume you have done it)
Just like CPP, C compiler also does not ensure order of the initialization of variables in different translation units(different C/CPP files). Hence declare the header file as
//GlobalInformation.h
namespace gi {
extern MapInformation mapInf;
};
In a function that you know would be called first initialize the variable. This way lazy-initialization can also be acheived in C.
Upvotes: 1
Reputation: 889
Perhaps a better solution is to create a global object that contains all your global data. Then pass a smart pointer to the classes that actually need to access this shared global data. Example:
class GlobalData
{
public:
int ticks_;
};
//Other file
class ThatNeedsGlobalData
{
public:
ThatNeedsGlobalData(std::shared_ptr<GlobalData> globalData);
};
This will save you some trouble.
Good luck!
Upvotes: 2
Reputation: 727
Be aware that having globals in multiple compilation units can easily lead to order-of-initialization problems. You may wish to consider replacing each global with a function that returns a reference. In your case, put this in one cpp file and declare it in the header:
namespace gi {
MapInformation& getMapInf()
{
static MapInformation result;
return result;
}
}
Upvotes: 17
Reputation: 24423
In header file only do
namespace gi {
extern MapInformation mapInf;
};
In CPP file provide the actual definition.
namespace gi {
MapInformation mapInf;
};
It will work as you intend.
If you are using the MapInformation across dynamic link library boundaries you might have to link against the library that includes the definition cpp file. Also on Window you might have to use dllimport/dllexport
Upvotes: 36