SuperStinger wrote: |
---|
"...the programmers philosophy that has been passed around that globals are evil and make ones code hard to read." |
The Problems
That depends on the complexity of the program and how you use those variables/objects. Global variables/objects are not bad, it's the way programmers use them which gives them a bad name. Generally speaking, global variables/objects are considered bad practice because:
● ...it's easy to form a function that directly refers to a global storage which means the function depends on a global variable/object to function. Removing the latter dependency can break the function.
● ...global storage is scoped to an invisible name-space. There's no structure to them; therefore, ambiguities can arise when you least expect it. Consider this:
1 2 3 4 5 6 7 8 9 10 11 12
|
// Global Name-Space:
int Data_;
struct Structure
{
int Data_; // OK. Data_ is scoped to Structure.
int GetData( ) const
{
return( Data_ ); // A
}
};
|
In the above code, the line marked "A" is ambiguous to us programmers. Why? Because the scope of global storage is always resolved implicitly. Because the identifier of the global storage and the data-member are the same -- hence the ambiguity -- the compiler may choose the data-member. However, we may not want that to happen; we may want the global storage instead (unlikely). To resolve this, we have two choices:
A) Use the "
this" pointer:
1 2 3 4
|
int GetData( ) const
{
return( this->Data_ );
}
|
or...
B) Use the scope-resolution operator on the global storage:
1 2 3 4
|
int GetData( ) const
{
return( ::Data_ );
}
|
However, using global storage within any function -- irrespective of scope -- causes the function to depend on that global storage as I've said before.
● ...and for the final reason, the destruction of a global object must happen after all other objects are destroyed. While this may not be a problem in some cases, it can be a pain in others.
The Resolution
The issue of global storage will always be around. The only thing you can do is:-
● ...resist the urge to write classes and functions that directly refer to a global variable/object and pass them by reference or value instead, or...
● ...begin an identifier with the scope-resolution operator to explicitly indicate that the identifier is within the global name-space and should not be changed. Then again, even this doesn't protect your code from code-breaking changes.
Note: Functions that depend on global storage marks the function's author a novice.
Wazzak