For me, I usually make a global class with all members static. All other classes will inherit from this global class.
I wonder if this is a good practice?
Anybody got any suggestions?
Generally try to avoid global variables as they introduce global state. And with global state you do not have referential transparency. Referential transparency is a good thing and global state is a bad thing. Global state makes unit tests pretty pointless for example.
When you have to though, I'd agree that most of the time the method you mentioned is fine. You can also declare the global variable in any .cpp file and then have in your .h file an extern to that global variable.
Best way? Carefully... :-)
Your suggested practice has not solved a single problem associated with global variables.
Private member data with access functions allow single point control of read/write and validation, improving robustness, maintainability, and ease of debugging.
Making the data members static simply reduces flexibility; you might want multiple independent global objects containing the same data structure. If there should only ever be one, use the singleton pattern.
Collecting unrelated global data into a single class breaks best practice regarding coupling and cohesion and is hardly OO.
This article relates to C and embedded systems, but is no less relevant to your question.
First, global state is bad. It seriously complicates understanding the program, since the behavior of any part can depend on the global variables. It makes it harder to test. It provides a way by which two far-distant functions can create an inconsistent state that may mess up another function, and that will be very difficult indeed to debug.
The nature of the global state doesn't matter. This is what's usually maligned about the Singleton pattern, for example.
However, having every class inherit from one global variable class is a bad idea. In C++, inheritance should be used sparingly, as it ties two classes together in implementation. It's usually a bad thing to have all the classes inheriting from one base class in any form, and C++ doesn't handle multiple inheritance really well. It would be really easy to get the "deadly diamond" effect, since if A inherits from B and they both inherit from Global, Global will appear twice in A's inheritance hierarchy.
There are 2 things that chagrined me: The use of global variables is bad, but sometimes it's difficult to do without, however I am chagrined by:
The clear abuse of inheritance
The wonderful dependency issue
The combination of the two has a staggering effect.
Let's say I create a class that will access a global variable, from your Anti-Pattern it gives:
#include "globals.h"
class MyClass: Globals // for my own sake I assume it's not public inheritance
{
};
Of course, the #include is mandatory in the header, since I inherit from it. Therefore each time I add / change one of the global, even one that is used by a single class... I recompile the whole application.
If we'd ever worked on the same team, that would earn you a very harsh, very stern comment... to say the least.
Ick!
A global variable is a global variable. Renaming it -- even with a name that makes it look like a member varaible, doesn't change that. Every problem that you have with a oridinary global variable you will still have with your global-variable-as-common-static-member scheme (and possibly a few new ones).
You are most likely looking for the Singleton pattern. That is not to say that all global variables need to use the pattern. But, when I have a global it is usually because I want only one instantiation for the entire program. In this case, singleton can work very well.
http://en.wikipedia.org/wiki/Singleton_pattern
Related
I don't really understand global variables. Why would anyone ever make one? It seems you could just put every variable in the entire program in a struct or a class?
Is this the right way to do things? It makes my code a lot more annoying to write, but it seems to solve a lot of problems.
Putting global variables inside structs is just a way of organizing them, and your global namespace ends up less polluted. However, those structs are still global, so it doesn't solve all problems. It's up to you to decide how and when to use them, and if it's a good design choice.
Global variables just mean variables with a life time as same as your application. They are not necessarily the same category of things.
Example:
You have a global variable called configs -- holding all your configuration like your color preferences, max thread number you want for certain purposes
You also have a global parser -- you want to parse same type of data here and there
You also have a global thread pool
These are things of very distinct nature. Putting them in a struct called globalVars is not the most readable way to organize source code, in my opinion
I have a few related methods, all of which use some global data (*), and all of which are to be implemented in a header. Should I...
place the methods in a class as static methods, with no instance data members, and the global variable(s) as a static class members?
place the methods in a namespace, and the global variable(s) in a ::detail sub-namespace?
Both of these options seem a bit ugly to me, but I'm wondering whether one of them has methodical benefits I'm missing, which should make me prefer it. I could try to bend-over-backwards and move the mutex into a .cpp file, so that might be a third option but it'll not be pretty...
(*) - in my specific case it's a mutex.
The only added bonus of using a class here, is that that compiler can complain if anyone ever reaches for that mutex (if you make it private, of course).
But, in both cases, you can only declare the data in the header, and you must still define it only once in some translation unit. I'd recommend you dispense with the in-header implementation, and hide the static mutex along with function implementation in the same translation unit.
From that point on, you can use a namespace, since it becomes a matter of organization only.
From a general "good practice" perspective, I would avoid any global data, and use static data as less as possible ( avoid the singleton syndrome ).
The first question is: Does it hurt to have several copy of those objects? Usually, if you are not managing hardware access or similar, it does not. Even if you are supposed to use only one, it is good to make it as general as possible and allows several instance of the class.
Also, static / global variables tend to carry issues with threads/processes, as it is some times difficult to figure how many copy of the static object you have.
So as a short answer: Put them in a class, as non-static, and put those "global" data into the class also.
If the reason to make those data is due to multiple threads or processes, then probably something is wrong at a design point of view.
If you do not have choice over a more appropriate solution, then I would use the namespace: a class using global parameters would break the encapsulation principle which any programmer would expect from your code.
EDITED:
After the edition in the question and trying to get closer of what the question is:
Supposing you require a wrapper around a mutex, which is unique per process.
class MyMutexWrapper // very minimal class, you should finish it.
{
MyMutex mutex;
public:
anyFunction();
};
Once you have this, you may create a single global instance of it and share it through the whole code. A better solution still to create it in any scope and pass it to any component that make use if it.
You could for example pass a reference.
This approach could seem more complex, but it avoid cross dependencies and make your code structure cleaner => you could then reuse it, extend it, maintain it...
I'm working with a large, old C codebase (an interpreter) that uses global variables a great deal, with the result that I cannot have two instances of it at once. Is there a straightforward (ideally automated) approach to convert this code to something reentrant? i.e. some refactor tool that would make all globals part of a struct and prepend the pointer to all variables?
Could I convert to C++ and wrap the entire thing in a class definition?
I would recommend to convert your project into C++11 project and change all your static vars into threadlocal.
This can be up to several days of work depending on the size of your project. In certain cases this will work.
I'm not aware of any "ready made" solution for this type of problem.
As a general rule, global variables are going to make it hard to make the code reentrant.
If you can remove all the global variables [simply delete the globals and see where you get compiler errors]. Replace the globals with a structure, and then use a structure per instance that is passed along, you'd be pretty much done (as long as the state of the interpreter instances is independent, and the instances don't need to know about each other). [Of course, you may need to have more than a single structure to solve the problem, but your global variables should be possible to "stick in a structure"].
Of course, making the structure and the code go together as a C++ class (which may have smaller classes as part of the solution) would be the "next step", but it's not entirely straight forward to do this, if you are not familiar with C++ and class designs.
Are you trying to make it reentrant in order to be able to make it multi-thread, and divide the work between threads?
If so, I would consider making it multi process, instead of multy-thread,
What I usually do with interpreters is go straight to a class with instance vars rather than globals. Not sure what you are interpreting, but it could be possible to pass in a file path or string container that the class interprets with an internal thread, so encapsulating the entire interpretation run.
It is possible to wrap the whole thing in a class definition, but it will not work for code that takes addresses of functions and passes them to C code. Also, converting a large legacy code base to be compilable by a C++ compiler is tedious enough that it probably outweighs the effort of removing the global variables by hand.
Barring that one, you have two options:
Since you need reentrancy to implement threading, it might be easiest to declare all global variables thread-local. If you have a C compiler that supports thread-locals, this is typically as easy as slapping a __thread (or other compiler-specific keyword) before every declaration. Then you create a new interpreter simply by creating a new thread and initializing the interpreter in the normal way.
If you cannot use __thread or equivalent, then you have to do a bit more footwork. You need to place all global variables in a structure, and replace every access to global variable foo with get_ctx()->foo. This is tedious, but straightforward. Once you are done, get_ctx() can allocate and return a thread-local interpreter state, using an API of your choosing.
A program transformation tool that can handle the C language would be able to automate such changes.
It needs to be able to resolve each symbol to its declaration, and preprocessor conditionals are likely to be trouble. I'd name one, but SO zealots object when I do that.
Your solution of a struct containing the globals is the right idea; you need rewrite that replaces each global declaration with a slot member, and each access to a global with access to the corresponding struct member.
The remaining question is, where does the struct pointer come from? One answer is a global variable that is multiplexed when threads are switched; a better answer if available under your OS is the get the struct pointer from thread local variables.
Recently I inherited 10 year old code base with some interesting patterns. Among them is static variables inside instance methods. Only single instance of the class is instantiated and I can hardly find reason to justify existence of those static variables in instance methods.
Have you ever designed instance methods with static variables? And what are your rationales?
If this pattern is considered bad then how to fix it?
Note: This question is not relevant to Static variables in instance methods
EDIT:
Some reading:
static class and singleton
http://objectmentor.com/resources/articles/SingletonAndMonostate.pdf
http://www.semantics.org/once_weakly/w01_expanding_monostate.pdf
This is a classic C++ implementation of the singleton pattern, described in one of Scott Meyers C++ books.
Singleton is a controversial pattern, so there is no industry-wide consensus on singleton being good or bad.
An alternative to singletons is a purely static objects. This question has a good discussion.
About the only time I've used static fields in an instanciable class has been as constants.
Generally speaking, you would want to create your class to be either entirely static, or entirely instanciable (with perhaps the exception of constants which you may want to keep static). With a singleton class they will behave in much the same way. The danger of mixing the two techniques is if you decide to make the class no longer a singleton, you might run into some strange behaviours in your now multi-instanced class.
Having a static variable is useful in a procedural function as it can serve as a kind of global variable with limited scope.
The only reason I can see to do something like this in a method would be to have the variable persist over many calls without having to declare a member variable that serves no other purpose. Honestly, I feel like this is just lazy programming and should be avoided.
In C++ one can have a 'GLOBAL FUNCTION', which means it does not belong to any class. I wondered if that isn't just a violation of the basic principles of OOP?
What would be the difference with using a global function or function that is static in a class? I'm thinking the latter is more OOP oriented. But I may be wrong however...
Does it not make it harder when writing a multithreaded applicaton?
A static function inside a class is as OO as a global function inside a module. The thing is in JAVA, you don't have the choice.
In C++, you can encapsulate your global functions inside namespaces, you don't need a dummy class to do this. This way you have modularity.
So of course you can put functions outside namespaces this way you have really global functions. But that's not very different from a JAVA kitchen sink class with a bunch of static functions. It's also bad code, but can be just ok for small projects :)
Also in C++ you have a lot of choices to have "global" function that actually are linked to a class, as operator functions, that may be for instance friends of a class.
EDIT
As for multithreading, you have to worry about global variables, not functions.
C++ facilitates many programming paradigms: structured, OOP, functional.
It makes no sense to choose for an OO approach for a small (hello world-style) program.
It makes no sense to use a structured approach for a modular program.
Next to that, static class functions are just better organized than 'free' functions; on top of that, they have access to an object's private variables - better encapsulation.
Static methods are able to access private static fields on the class they're in, but that's about the only difference from global functions.
Global functions are there because C++ is roughly a superset of C, and C has global functions. C can be used for both OOP and non-OOP programming.
And, frankly, does it really make a difference whether you type std::Math::max or std::max?
Totally agree with other answers and i want to add my advice. Static functions and static methods are almost same things and abusing them can lead to poor oo design. If you want to keep your object model clean you should use static functions/methods only if:
they do not produce result that depends on state of object
they do not change state of object