Quote:Original post by StratBoy61
In my opinion, there are at least two good reasons to use singletons (and thus yes, global objects) :
1) optimization
2) object's scope and lifetime : If the object's lifetime is the same as the whole program, then it makes half sense to be a global object. If on top of that, it has to be accessed anywhere in the code, then it makes the second half sense. Think of a database accessor object for instance.
Optimization should never be a part of design discussion. Scalability and overhed yes, but not optimization.
The database accessor isn't best example either. Typical SQL accessors revolve around connections and connection specific objects that live only for the duration of the connection. Also, most connections cannot be shared between threads, they need to be recreated if a connection error occurs, and similar. Methods for accessing it are obviously global, but not much else.
Singletons and globals have their place. But in even basic OO application, they should be very limited.
I have ran across an application converted from C into C++. It was fully object oriented. It contained several hundred classes, all singletons, containing C code, and named after the file they were in.
The final decision about what is a singleton and what isn't comes down do separating function from form.
A singleton should also be able to start-up its own internal state at any time for any reason, without external dependencies. If it depends on other objects, then it'll make a poor singleton, since it may cause random failures at most unusual times. If singleton isn't able to perform it's own state initialization, or is initialized manually, then it's not a singleton, just a global variable.
Going by the above example, even if window size won't change during application life-time (is this true?), it will be initialized after some event, and most likely depends on several other pre-conditions (validating the driver, checking for resolution, allocating handle, ...). And that's a lot for a singleton to handle.
int FPSCount = 0;char* FPSCountTxt = "";DWORD timeCurrentTime = 0;DWORD timeDemoStartTime = 0;DWORD timeElapsedTime = 0;char* timeElapsedTxt = "";
This may seem like good candidate for singleton, but it really isn't. There's a special DemoStartTime. So there's a difference on where these variables will be used.
Going back to use of this class. Where will it be called? There's bound to be a render loop that will time the rendering process. And the measurment becomes a member of the window class. Each window has its own measurement. Even more, the fps monitor should be part of scene definition, since this is what we're interested in. Time when scene was started, number of frames rendered, etc. On top of that, you can of course add extra global counter for application life-time.
// Testing Variablesbool showHelp = FALSE;bool showWireframe = FALSE;bool showFog = FALSE;bool enableLighting = TRUE;bool enableSound = TRUE;bool enableFrustum = TRUE;
These are also not globals. In order for these variables to have any effect, the rendering system needs to be between fully initialized and not being destroyed. And that is much less than full application life-time.
These variables are prime candidate for being completely hidden within renderer class, and being changable only though accessors. Even more, this allows you to query device capabilities and log any problems with setting these flags.
bool MouseMove = FALSE; int MouseButton = -1; //Mouse PositionGLfloat MoveXcoord, MoveYcoord; int clickXcoord, clickYcoord;
Mouse events seem like a good idea for a global. Until you need to write a demo that will simulate mouse moves and mouse clicks. Who will then have the authority, system mouse event driver, or your demo driver? And how will you disable one of them? So these must definitely not be globals of any kind - even more, all these variables are extremly short live, ideally, their life-span 0 seconds, since they become invalid the moment system passes them on. From design perspective, these are prime candidate for either method parameters, or message queue.
There is really very little reeason for globals - ever. I suppose the only ones that really warrant such would be invariants. Everything else goes against OO design (except valid exceptions).