Is it possible to create a variable globally accessible to all classes in my program in which if I change it's value from one class it will also change for all other classes?
If so, how do I implement such?
Is it possible to create a variable globally accessible to all classes in my program in which if I change it's value from one class it will also change for all other classes?
If so, how do I implement such?
Everyone keeps parroting that "globals are evil", but I say that pretty much everything can be used or misused. Also, if globals were intrinsically bad, they simply wouldn't be allowed in the first place. In the case of globals, there is quite the potential for accidental misuse to very negative consequences, but they are 100% fine if you actually know what you are doing:
// globals.h - for including globals
extern int globalInt; // note the "extern" part
// globals.cpp - implementing the globals
int globalInt = 667;
It may also be a very good idea to use namespaces to avoid naming conflicts and keep the scope cleaner, unless you are particularly meticulous with your naming conventions, which is the olden "C" way to do namespaces.
Also, and especially if you are using multiple threads, it might be a good idea to create an interface for accessing the encapsulated global stuff that will also have modular locks or even be lock-less wherever possible (for example direct use of atomics).
But a global is not necessarily the only solution. Depending on what you actually need, singletons or static class members might do the trick while keeping it a little more tidy and avoiding the use of evil globals.
Such variable have to be defined once somewhere but then used in different compilation units. However, in order to use something, you know, you need to tell the compiler that it exists (declare it). extern
keyword lets you declare that something exists somewhere else.
In order to structure your code you can do what xkenshin14x (kind of?) proposed:
global.h
#pragma once
#include <string>
// Declaration
namespace global
{
extern int i;
extern float f;
extern ::std::string s;
}
global.cpp
#include "global.h"
// Definition
namespace global
{
int i = 100;
float f = 20.0f;
::std::string s = "string";
}
main.cpp
#include "global.h"
int main(int argc, char *argv[])
{
std::cout << global::i << " " << global::f << " " << global::s;
return 0;
}
It is good to use a namespace in this case as it lets you to avoid name collisions which are inherent for global variables.
Alternatively, it is possible to encapsulate all global stuff inside a one "global" object. I quoted word "global" because indeed this object is static to a global function so technically no global variables involved :)
Here is a header only implementation:
global.h
#pragma once
class Global
{
public:
int i = 100;
float f = 20.0f;
// and other "global" variable
public:
Global() = default;
Global(const Global&) = delete;
Global(Global&&) = delete;
static Global& Instance()
{
static Global global;
return global;
}
};
namespace {
Global& global = Global::Instance();
}
// static Global& global = Global::Instance(); if you like
test.h
#pragma once
#include "global.h"
struct Test
{
void ChangeGlobal() {
global.i++;
}
};
main.cpp
#include <iostream>
#include "global.h"
#include "test.h"
int main()
{
Test t;
std::cout << global.i << " " << global.f << std::endl;
t.ChangeGlobal();
std::cout << global.i << " " << global.f << std::endl;
return 0;
}
There are at least two benefits in a such approach:
Global
class you can add variable accessors with mutexes inside where it is needed. For example, void SetSomething(const Something& something) { ... }
If you just use this global variable in UI thread(for QApplication ui app) or main thread(for QCoreApplication console app),it will be convenient to code and you may design a custom data struct.But if you use it in multithread environment,you should need mutex or atomic to protect global variables.
Global variables should be avoided as you probably know.
But you could create a header file for the global variables and #include "globals.h" in each place you want to use it in. Then you can use each variable normally.