Can I use a global variable in this scenario? - c++

After reading some SO threads on this topic: I've come up with these reasons for why global variables/singletons are bad.
It becomes increasingly difficult to understand functions that the global state, as the code grows, more and more functions will modify that global state.
It makes unit testing harder.
It hides dependencies.
You will have to rewrite code if someday it turns out that your global variable is not actually a singular object/variable.
I want to make a game in C++, and there will be a "heightmap object" that represents the landscape of the world in my game as heightmap. This heightmap can change. I want to use a global object for it. (I don't expect to run into static initialization order issues, as there won't be any other static variable that references this heightmap object).
Now, I know global state is bad, and global mutable state is even worse, for those above reasons. But it seems really, really cumbersome to do the alternative: Create a heightmap object at main() scope, and pass that heightmap object to every single function that wants to use it.
What if I'm 100% sure that there will only be one heightmap in my application? Also, since this is a small, solo project, I have faith that I will be able to understand what each function is doing to the global state? And I don't see how the use of a global variable in this this case hurts unit testing. If I want to use a mock heightmap, couldn't I just do globalHeightmap = generateMockHeightmap(); before calling the function that I want to test?

As certain as you may be about the characteristics of your project right now, I can pretty much assure you that at some point in the future you'll need to modify the code that relies on this global variable. At that point the global variable will likely come back and make it harder for you to figure out the needed changes because state isn't hidden (for example what if you accidentally change the state instead of reading from it - then the entire program is affected at some random point in the future). I can't overstate how important it is for program maintenance and debugging to minimize state mutation points and global variables are pretty much the antithesis to that goal.
Just overriding the global state map for your unit test seems fragile. What if you need to restore the old state, or mutate between states in the test? Then you wind up with a bunch of save/set/restore code.
What if you ever want to add a threading model to your application? Using global state will make that transition that much more complicated.
What if someone else helps you out with the project a year from now? Will they be able to understand the code? Will you be able to understand it a year from now (I know that I always try to write obvious code and add comments where it's not specifically because I might be the person that comes back a year later and no longer remember a thing about the mechanism).
Finally, if a non-global-variable approach seems like too much work or too complicated that probably means your alternate approach is too complicated or needs another idea/rework. There's no reason that you can't stash the heightmap into an object that's created at the appropriate high-level game object and passed/stored in lower level objects as needed.

Related

"State pattern" vs "one member function per state"?

My class has 3 states. In each state it does some work, and goes to other state, or remains in the same state (in 95% or more cases it will stay in the same state). I can implement state pattern (I assume you know it). The alternative, which I pretty like, is this:
I have a member function per state, and also a pointer to member function, which points to the current state function. When in a state I want to go to another state, I just point that function pointer to another state function. (maybe this isn't completely equivalent to state pattern, but in my case it works fine).
Those two ways are almost identical, I think.
So, my questions are:
Which solution is better (depends on what)?
Is it worth to declare a class per state (which will have only one function)? I think that would be artificial.
What about performance? isn't creating new object of state class (in case of state pattern) bring with it a slight overhead? (Sure state classes shouldn't have members, but anyway it should cost something)
You don't really mention the constraints under which your program will run, so it's hard comment specifically about overheads of one implementation over the other, so I'll just make a comment about code maintainability.
Personally I think that unless your state machine is extremely simple and will stay simple, then declaring a class per state is far more maintainable, extensible & readable. A good rule of thumb might be that if you can't look at the code in your class and keep the entire picture in your head, then your class is probably doing too much. The small overhead you pay in declaring a class per state is likely to be well worth the productivity gains you will get from writing modular code (or anyone else who ends up maintaining it). I've come across far too many 'uber' classes that are essentially one big (very hard too maintain) state machine that probably started out as a simple state machine, to recommend otherwise.
The 'S' and 'O' portions of the SOLID acronym (https://en.wikipedia.org/wiki/SOLID_(object-oriented_design) are always good things to keep in mind.
It depends if you need to access private members of your object or not. If not, then an out-of-class implementation breaks your code in smaller fragments and may be preferable because of this (but this is non objective : the two solutions have pros and cons).
It's not necessary, but adds a layer of abstraction and loosen the coupling. Using an interface, you can change each implementation without affecting the others (e.g. adding class fields...)
Doesn't matter so much, allocating a new empty class or calling a function have same magnitude of overhead.

What is the need of global objects in c++?

I know that C++ also allows to create global objects of class and struct.
#include <iostream>
using std::cout;
class Test
{
public:
void fun()
{
cout<<"a= "<<a;
}
private:
int a=9;
};
Test t; // global object
int main()
{
t.fun();
return 0;
}
When & where should i use global objects? Is there any specific use of global objects? Please help me.
The short answer is there is no need.
The long answer is that it can sometimes be convenient. Unfortunately convenience is subjective, and what one finds to convenient another might find to be too lenient.
Global objects have issues (among which muddying data flows in the code and access synchronization), but sometimes one might find it convenient nonetheless to use one because it makes something easier. It can indeed remain easier, or it can prove a maintenance burden, but that only the future can tell...
... If you can avoid global objects, in general you should be better off. In practice, though, you will rarely encounter issues before programming at scale; for toy examples and students' projects there is rarely an issue, which is why beginners fail to understand why more seasoned developers avoid them like the plague.
In a complex project, you shouldn't. You should always be within a namespace if you plan to use you're assembly in other projects.
An example of something that might be that high in scope is an operator overload or an interface that you define which will be used many times.
Good practice...organize your project to use descriptive and intuitive namespaces.
Global is really only useful in simple project that simple don't use namespaces.
The question is malposed: is there a need for if wile and do, since we can do all with just for ?
The technical answer is "no, there is no need: the fact we can do without proves it". But a little more pragmatism show us that reducing every control flow into a single keywork makes code harder to track and follow. So it is technically possible but not always convenient.
Now: can we do without global objects?
A first non-answer is "yes, with singletons". But a singleton is a static object obtained through a function. They are not that conceptually different if not for a design flaw (known as "static initialization order fiasco") due to C++ not specifying global initialization object order essentially to allow multiple translation unit to coexist in a same linked executable. Singleton allow to circumvent that problem, but are essentially a workaround to allow global "things" to exist.
The existence of that flaw (and the singleton technique) is wat makes many "teachers" to draw some "moral" suasion like "never use global objects, or the flame of hell will burn your ass-hair". But that soon do std::cout << "hello world" and immediately loose ALL their credibility.
The point is that without "globals" everything is "scope local" and there is no "dynamic scope" in C++: if funcA calls funcB, funcB cannot see funcA locals, hence the only way to access things across scopes is parameter passing of reference or pointers.
In context which are mostly "functional", the missing of "dynamic scopes" is compensated by "lamba captures", and everything else will go as paramenter.
In context which are mostly "procedural", the need of a "state" that survives scopes and can be modified while going in and out is more suited for global objects. And that's the reason cout is that. It represent a resource theat pre-exist and post-exist the program, whose state evolves across various calls. If there is no global way to access cout, it should be initialized in main, an passed as a reference parameter to whatever function call: even the one that have no output to give, since they may call themselves something else that has output to give.
In fact you can think to global object as "implicit parameters passed to every function".
You can warp in global functions but -if functions themselves can be objects and object themselves can be functional- why saying global objects are bad and global functions can be right?
The actual only reason, in fact, turns out to be the static initialization order fiasco
I would say that global variables are needed for backwards compatibility with c. That is for sure, and this is the only hard reason I see. Since classes and structs are essentially the same, it probably didn't make much sense in forbidding only one.
I don't know any patterns or use-cases that are universally accepted as a good practice, that would make use of global objects. Usually global objects, sooner or later, lead to mess if not interacted with properly. They hide data flow and relationships. It is extremely easily to trip over it.
Still, I have seen some libraries exposing some objects as globals. Usually things that contain some static data. But there are other cases too, notable example being standard library's std::cout and family.
I won't judge if it's good or bad approach. This is too subjective IMO. You could probably use singletons, but one might argue, you can work on a global object under a contract etc. etc.

RNGs and global variable avoidance

I'm wondering about this. I've heard that global variables are bad, that they hurt the maintainability, usability, reusability, etc. of the code. But in this case, what can I do otherwise? Namely, I have a "pseudo-random number generator" (PRNG) and as one may know, they involve an internal state that changes every time new random numbers are generated. But this seems like the kind of thing that needs to be a global! Or a "static" member of an RNG class, but that's essentially a global! And globals are bad!
So, what can I do? The obvious thing is to have something like this (really stripped down):
class RNG {
private:
StateType state; // this is the thing one may be tempted
// to make "static", which ruins the
// whole idea
public:
RNG(); // constructor seeds the RNG
~RNG();
int generateRandomInt();
};
But we need to seed that good, if we're going to create an instance of this every time we need a random number in some function or class. Using the clock may not work, since what if two instances of type "RNG" are created too close together? Then they get the same seed and produce the same random sequence. Bad.
We could also create one master RNG object and pass it around with pointers (instead of making it global, which would put us back on square 1), so that classes that need random numbers get a pointer to the RNG object in them. But then I run into a problem involving save/load of these objects to/from disk -- we can't just "save the RNG" for each instance, since we have only one RNG object. We'd have to instead pass an RNG into the load routines, which might give those routines different argument lists than for other objects that don't use the RNG. This would be a problem if, e.g. we wanted to use a common "Saveable" base class for everything that we can load/save. So, what to do? Eliminate the common "Saveable" base and just adopt a convention for how the load/save routines are to be made (but isn't that bad in and of itself? Oy!)?
What is the best solution to this that avoids the hostile-to-maintainability problems of globals yet also does not run into these new problems?
Or is it in fact okay to use a global here, as after all, that's how the "rand()" builtin works anyway? But then I hear that little thing in the back of my mind saying "but... but but but, globals are bad! Bad!" And from what I've read, there seem to be fairly good reasons to think them bad. But it seems like avoiding them creates new kinds of difficulties, like this one. It certainly seems harder to avoid globals than avoid "goto"s, for example.
There's some merit to your reluctance. You may want to substitute another generator for testing for example, that spits out a deterministic sequence that contains some edge cases.
Dependency Injection is one popular method for avoiding globals.
A random number generator is one of those things that is more OK to be global. You can think of it as:
-A RandomNumberFactory, a design pattern that uses a global factory, and it builds random numbers for you. The factory is of course constant semantically (in C++ you might use the keyword "mutable" internally, if that means anything to you.)
-A global constant (global constants are ok, right?) that gives you read-only access to the global constant randomNumber. randomNumber just happens to be non-deterministic, but it's constant in that of course no application is going to write to it.
-And besides, what's the worst that could happen? In a multithreaded application your RNG will yield non-deterministic behavior? Gasp. As #Mark Ransom pointed out above, yes that is actually a drawback as it makes testing harder. If this is a concern to you, you might consider a design pattern that writes this out.
It sometimes makes sense to use globals. No one can categorically say your code should not have any global variables, period.
What you do need is to be aware of the issues that can arise from global variables. If your application's logic needs global variables and it is possible for it to be called from a multi-threaded environment, then there is nothing inherently wrong with that, but you must take care to use locking, mutexes, and/or atomic reads/writes to ensure correct behavior.

What is a good way to share an object between classes?

What is a good way to share an instance of an object between several classes in a class hierarchy? I have the following situation:
class texture_manager;
class world {
...
std::vector<object> objects_;
skybox skybox_;
}
I currently implemented texture_manager as a singleton, and clients call its instancing method from anywhere in the code. texture_manager needs to be used by objects in the objects_ vector, by skybox_, and possibly by other classes as well that may or may not be part of the world class.
As I am trying to limit the use of singletons in my code, do you recommend any alternatives to this approach? One solution that came to mind would be to pass a texture_manager reference as an argument to the constructors of all classes that need access to it. Thanks.
The general answer to that question is to use ::std::shared_ptr. Or if you don't have that, ::std::tr1::shared_ptr, or if you don't have that, ::boost::shared_ptr.
In your particular case, I would recommend one of a few different approaches:
One possibility is, of course, the shared_ptr approach. You basically pass around your pointer to everybody who needs the object, and it's automatically destroyed when none of them need it anymore. Though if your texture manager is going to end up with pointers to the objects pointing at it, you're creating a reference cycle, and that will have to be handled very carefully.
Another possibility is just to declare it as a local variable in main and pass it as a pointer or reference to everybody who needs it. It won't be going away until your program is finished that way, and you shouldn't have to worry about managing the lifetime. A bare pointer or reference is just fine in this case.
A third possibility is one of the sort of vaguely acceptable uses of something sort of like a singleton. And this deserves a detailed explanation.
You make a singleton who's only job is to hand out useful pointers to things. A key feature it has is the ability to tell it what thing to hand out a pointer to. It's kind of like a global configurable factory.
This allows you to escape from the huge testing issues you create with a singleton in general. Just tell it to hand out a pointer to a stub object when it comes time to test things.
It also allows you to escape from the access control/security issue (yes, they create security issues as well) that a singleton represents for the same reason. You can temporarily tell it to pass out a pointer to an object that doesn't allow access to things that the section of code you're about to execute doesn't need access to. This idea is generally referred to as the principle of least authority.
The main reason to use this is that it saves you the problem of figuring out who needs your pointer and handing it to them. This is also the main reason not to use it, thinking that through is good for you. You also introduce the possibility that two things that expected to get the same pointer to a texture manager actually get pointers to a different texture manager because of a control flow you didn't anticipate, which is basically the result of the sloppy thinking that caused you to use the Singleton in the first place. Lastly, Singletons are so awful, that even this more benign use of them makes me itchy.
Personally, in your case, I would recommend approach #2, just creating it on the stack in main and passing in a pointer to wherever it's needed. It will make you think more carefully about the structure of your program, and this sort of object should probably live for your entire program's lifetime anyway.

external side effect in constructor

Look at this code:
#include <framework_i_hate.h>
int main() {
XFile file("./my_file.xxxx", "create");
XObject object("my_object");
// modify the object
object.Write();
}
Try to guess where object will be saved... yes, you guessed it. I think this is too magic, I'd like to write something like object.Save(file), but it's not necessary. Obviously there is global variable inside framework_i_hate.h that it is modified during the file constructor. What do you think about this side effect inside constructor?
How can this behavior be hidden?
A bonus to who guess the framework.
Very muddled hard to understand post and the question in the end is very rhetorical.
Global variables are evil, what else to add?
What can be said about this that isn't already obvious enough: It's a fairly nasty side effect, because:
the resulting behaviour is unexpected and not predictable at all, unless you know that framework well.
global program state usually isn't a good idea in object-oriented programming. (In fact, global state is probably never a good idea, so best avoid it if you can.)
it's fairly likely that this framework isn't thread-safe, either. (Think about what happens when two concurrent threads both create an XFile object each, and one of these threads then writes an XObject... where will it end up being saved?)
While this thread is tagged C++ and not about .NET, I have seen this "anti-pattern" before in a less severe and much more sane form, namely with DB transaction scopes.
I'd prefer to see the relationship between XFile and XObject be explicit, I agree that this "magic" is too well hidden. I also question why the object is given a name, unless there are other parts of the API where the name is significant.
Global variables are despised for many reasons, this is just one example.