// Window Enviroment Settings ----------------------------
HDC hDC = NULL;
HGLRC hRC = NULL;
HWND hWnd = NULL;
HINSTANCE hInstance;
DEVMODE DMsaved;
bool keys[256];
bool active = TRUE;
bool fullscreen = FALSE;
bool scrVSync = FALSE;
int scrWidth = 1024;
int scrHeight = 768;
int scrBitDepth = 32;
// Camera
CCamera objCamera;
float CAMERA_FARPLANE = 50000;
float FOV = 52.0f;
// Font & Text variables
GLuint baseFont;
GLuint baseBitmapFont;
GLuint texBitmapFont;
// Textures
GLuint texCrosshair;
GLuint texHud;
// Mouse Variables
// Move & click
bool MouseMove = FALSE;
int MouseButton = -1;
//Mouse Position
GLfloat MoveXcoord, MoveYcoord;
int clickXcoord, clickYcoord;
// timing Variables
int FPSCount = 0;
char* FPSCountTxt = "";
DWORD timeCurrentTime = 0;
DWORD timeDemoStartTime = 0;
DWORD timeElapsedTime = 0;
char* timeElapsedTxt = "";
// Testing Variables
bool showHelp = FALSE;
bool showWireframe = FALSE;
bool showFog = FALSE;
bool enableLighting = TRUE;
bool enableSound = TRUE;
bool enableFrustum = TRUE;
Advice on global variables
Hi,
Reading several threads and other resouorces, I keep hearing global variables are a bad thing.
Is this correct ? and what is the best solution to avoid using globals?
Here is a quick example from a project, I'm not looking for anyone to re-code this, just advice on better programming techniques.
Already this is getting very large, and very messy, and this is still a simple project.
Most of the examples I have been following are from NeHe, which I'm told some of his code is actually C, not C++ !!
Although the 'code downloads' for the lessons are labelled as Visual C++
(sorry noobie alert) I'm still learning the difference.
Besides the point anyway, but is there a better way to structure an application, and avoid so many globals ??
Thanks
When people tell you something is bad or wrong (programming-wise), they usually mean that you shouldn't use it unless the alternative is worse. For instance, many sources will tell you that goto should never be used. However, there are times when it can be useful.
I would suggest trying to avoid using global variables as much as possible. There's very little security regarding when and how these variables can be altered. This can make debugging and maintenance much more difficult.
Personally, I would try to wrap some of the values up into a class or struct, just for the sake of readability and maintenance. All the screen stuff can go into a class. The camera, font and mouse variables can also be placed into their own classes. At program start up, just create instances of the necessary classes. This makes passing the values around to functions much easier. And, if you find you need to add another value, it can simply be added to the appropriate class, rather than needing to update the function and every where the function is called.
I would suggest trying to avoid using global variables as much as possible. There's very little security regarding when and how these variables can be altered. This can make debugging and maintenance much more difficult.
Personally, I would try to wrap some of the values up into a class or struct, just for the sake of readability and maintenance. All the screen stuff can go into a class. The camera, font and mouse variables can also be placed into their own classes. At program start up, just create instances of the necessary classes. This makes passing the values around to functions much easier. And, if you find you need to add another value, it can simply be added to the appropriate class, rather than needing to update the function and every where the function is called.
That kind of thing definitely gets ugly and doesn't scale (as far as maintainability goes at least). Since you're posting it as an example, you're already aware of that.
I think every time this question comes up, a huge debate on global variables versus singletons ensues. I don't have the time or patience to get into that argument because they are always argued about as if the opposing side thought the other was a silver bullet.
What I *will* say, however, is that at the absolute very least, instead of letting naked booleans and such sit out there, they should probably be grouped together in the way that makes most logical sense to you. Perhaps a "static config" (something that doesn't change, that is read once from a config file of sorts) and a "dynamic config" (user-changeable settings and the likes, which can change).
How you control access to them depends on the constraints you want to put on your software, so that's up to you.
I think every time this question comes up, a huge debate on global variables versus singletons ensues. I don't have the time or patience to get into that argument because they are always argued about as if the opposing side thought the other was a silver bullet.
What I *will* say, however, is that at the absolute very least, instead of letting naked booleans and such sit out there, they should probably be grouped together in the way that makes most logical sense to you. Perhaps a "static config" (something that doesn't change, that is read once from a config file of sorts) and a "dynamic config" (user-changeable settings and the likes, which can change).
How you control access to them depends on the constraints you want to put on your software, so that's up to you.
Hey there,
I personally like to use 'smart' singletons, as desbribed below.
IMO, they pretty much look like global variables, except that they have the advantages that classes have.
Cheers
StratBoy61
I personally like to use 'smart' singletons, as desbribed below.
#include <memory>class MySettings{private: const static std::auto_ptr<MySettings> m_staticInstance; tbthSettings();public: virtual ~MySettings(); static MySettings *getUniqueInstance(void) { return m_staticInstance.get(); }};const std::auto_ptr<MySettings> MySettings::m_staticInstance(new MySettings()); // in cpp file...
IMO, they pretty much look like global variables, except that they have the advantages that classes have.
Cheers
StratBoy61
Global variables are a Bad Thing in that they are commonly used by programmers who don't know how to do proper OO design but who don't know that they aren't doing proper OO design. A similar thing is true of singletons: People usually use singletons because they don't know how to avoid global variables (because they don't know proper OO design) but they think that singletons "don't count" as global variables.
You can have global variables with class type.
Quote:IMO, they pretty much look like global variables, except that they have the advantages that classes have.
You can have global variables with class type.
Quote:Original post by StratBoy61Although this may work for you, I wouldn't be too quick to recommend the use of singletons as a solution to the global variable problem. There are many aspects of singleton usage that are less than obvious (not the least of which is order of construction and destruction).
Hey there,
I personally like to use 'smart' singletons, as desbribed below.
*** Source Snippet Removed ***
IMO, they pretty much look like global variables, except that they have the advantages that classes have.
Cheers
StratBoy61
@The OP: I would at least read this before deciding whether or not to make use of singletons in your own code.
The Law of Demeter states that you should only use objects which you've:
The objective (and result) of this law is to reduce coupling between your modules, which in turn results in modifications being more local (you don't have system-wide dependencies to follow).
Therefore, if an object or method expects to manipulate something, it should either create it itself or expect to receive it as an argument (or constructor argument). Otherwise, the object becomes too reliant on external structure, which make its testing, reuse and modification much harder, and also creates a direct dependency between the object and the used element.
Neither global variables nor singletons are valid with respect with the law (and, in fact, neither is better than the other anyway, because they are destined to solve different problems anyway).
- Created yourself, or
- Received as an argument.
The objective (and result) of this law is to reduce coupling between your modules, which in turn results in modifications being more local (you don't have system-wide dependencies to follow).
Therefore, if an object or method expects to manipulate something, it should either create it itself or expect to receive it as an argument (or constructor argument). Otherwise, the object becomes too reliant on external structure, which make its testing, reuse and modification much harder, and also creates a direct dependency between the object and the used element.
Neither global variables nor singletons are valid with respect with the law (and, in fact, neither is better than the other anyway, because they are destined to solve different problems anyway).
eeerrr !!
OK so I'm going for a class or struct right ?
Now the question, which one ?
Structure, doesn't seem an improvement, other than, ... well .. it's structured !
Would be a bit more organized I guess:
example:
myWindow.fullscreen = TRUE;
myWindow.scrWidth= 1024;
etc etc
if anything this is more code no ??
having to put "myWindow." before everything
OK so I'm going for a class or struct right ?
Now the question, which one ?
Structure, doesn't seem an improvement, other than, ... well .. it's structured !
Would be a bit more organized I guess:
typedef struct sWindow{ bool fullscreen; int scrWidth; int scrHeight; int scrBitDepth; } myWindow;
example:
myWindow.fullscreen = TRUE;
myWindow.scrWidth= 1024;
etc etc
if anything this is more code no ??
having to put "myWindow." before everything
1.) That's a C idiom for creating structs. In C++, you don't need the typedef:
2.) I think you've missed the point. Avoiding global variables does not mean wrapping them in a struct(!) - rather, it involves designing your program in such a manner as they aren't needed. Pass them as arguments - use classes to encapsulate other objects which are tightly related to ('part of') themselves. A highly simplified example:
EDIT: D'oh.
EDIT 1306BST 25/03/07: Missed a semicolon
[Edited by - TheUnbeliever on March 25, 2007 6:27:55 AM]
// C idiom - works but can be considered deprecatedtypedef struct point_{ int x; int y;} point;// C++ idiomstruct point{ int x; int y;};
2.) I think you've missed the point. Avoiding global variables does not mean wrapping them in a struct(!) - rather, it involves designing your program in such a manner as they aren't needed. Pass them as arguments - use classes to encapsulate other objects which are tightly related to ('part of') themselves. A highly simplified example:
// Bad#include <iostream>int x;void tripleX(){ x *= 3;}int main(){ x = 3; doubleX(); std::cout << x;}// Good#include <iostream>int triple(int input){ /* Double is no longer tied to one variable - any int can be passed to it. Also, we better abstract the concept of doubling a number - with the result that the code is easier to reuse. */ return input *= 3;}int main(){ int x = 3; std::cout << double(x); /* Also, a return value saves us a line of code in this example. Although, this is of course also a case of design - it might sometimes not be what we want! */}
EDIT: D'oh.
EDIT 1306BST 25/03/07: Missed a semicolon
[Edited by - TheUnbeliever on March 25, 2007 6:27:55 AM]
ok, I get what your saying.
Maybe I am doing something more dramatically wrong here.
just an example of various function I'm using:
CreateGLWindow(WND_TITLE, scrWidth, scrHeight) // in main
glOrtho(0, scrWidth, 0, scrHeight, -1, 1); // various times (fonts, hud, crosshair)
Draw_loadingScreen(scrWidth, scrHeight); // in render
Draw_creditsScreen(scrWidth, scrHeight); // in render
That's just an example of 2 variables (scrWidth, scrHeight)
I could list a dozen more, for mouse and key presses
Surely these need to be globals right ?
Maybe I am doing something more dramatically wrong here.
just an example of various function I'm using:
CreateGLWindow(WND_TITLE, scrWidth, scrHeight) // in main
glOrtho(0, scrWidth, 0, scrHeight, -1, 1); // various times (fonts, hud, crosshair)
Draw_loadingScreen(scrWidth, scrHeight); // in render
Draw_creditsScreen(scrWidth, scrHeight); // in render
That's just an example of 2 variables (scrWidth, scrHeight)
I could list a dozen more, for mouse and key presses
Surely these need to be globals right ?
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement