tags:

views:

732

answers:

6
+4  A: 

does this help?

http://stackoverflow.com/questions/137975/what-is-so-bad-about-singletons http://steve.yegge.googlepages.com/singleton-considered-stupid

Rephrased: A singleton is a glorified global, so just 'implement' it as a global.

Dustin Getz
Suppose the singleton opens a config file or a logging stream, id you remember to call the global setup function before your first use of the log or config?
Martin Beckett
@MGB its still a class with ctors and stuff
Dustin Getz
Not really. It misses the point of my question. I'm refering to the way to implement a singleton in C++. Not to the question if one should use one in the first place.
Ben Strasser
Its also lazily initialized (*unlike a global). So if it is empensize you dont incur the initialization cost if you dont use it.
Martin York
+3  A: 

The construction of static MySingleton singleton; gets called on the first use. (When get_instance() is called.) If it is never called it never calls the constructor. Your method will call the constructor at static construction time. The previous method allows for the order and timing of the constructors being called. You method will order the construction of each singleton according to the compiler static initialisation order.

Charles Beattie
It is implementation defined when the constructor of local static variables are run. Using the second variant you have reliable behavior. Also you can add a flag and get the lazy behavior in a portable way.
Ben Strasser
It is implementation defined when the constructor of local static variables are run. -> Not true when they are in a function or an if statment etc... The memory can get allocated at anytime before main() but the constructor of these types of statics is called when the program pointer passes it for the first time. When they're defined outside a function of some sort then when the constructor gets called is implementation specific.
Charles Beattie
@Ben. The order of evaluation of staic function variables is well defined. It is at the point of first use. Thus giving you the equivalent of the flagged you suggest but done by the compiler (thus less chance of an error (not saying compielr is perfect but usually better than a human)) (also on gcc it is thread safe, and hopefully thread safe be standard in the next version of C++).
Martin York
+6  A: 

According to the party line (E. Gamma, R. Helm, R. Johnson, and J. Vlissides. Design Patterns: Elements of Reusable Object-Oriented Software. Addison-Wesley, Reading, MA, 1995, p. 128), the singleton offers the following advantages over the solution you propose.

  • You can refine the operations and the representation e.g. through subclassing.
  • You can change your mind at a later point and have multiple instances.
  • You can override the singleton's methods polymorphically.
  • You can configure your application at runtime by initializing the singleton instance with the class you need.

Having said that, in most cases I consider the additional complexity excessive and rarely use the pattern in the code I write. But I can see its value when you design an API that others will use.

Diomidis Spinellis
"You can change your mind at a later point and have multiple instances." In practice this isn't true because it, er, encourages coupled code.
Dustin Getz
@Dustin Getz How does it encourage coupled code any more than anything else?
Imagist
All of these can be accomplished by free functions and using function pointers internally to change the implementation. The only difference is the interface. ie do you like typing instance() or not.
Greg Rogers
True, you can do OO programming with structures containing function pointers. The Unix kernels do it for implementing VFS. But language-supported OO is a lot nicer.
Diomidis Spinellis
A: 

The problem with just using free functions is that those don't by default get shared persistent behavior, like your singleton class can get with member variables and constants.

You could proceed to use static global variables to do the same thing, but for someone trying to figure that out, that makes the scope of what they have to look at to understand those routines' behavior nearly unlimited. With a singleton class, everything is nicely organized into one class for the reader to examine.

T.E.D.
I don't see why it is harder to learn how to use non error prone static global variables, than learning how to do the error prone voodoo stuff necessary to ensure that there exists only one instance. Newbies normally use global variables far too often. This shows that the concept of global data is pretty intuitive.
Ben Strasser
+1  A: 

To have functions + static data emulate the singleton pattern would rely on C++'s file scoping and separate-compilation. These are compiler constructs rather than language constructs. The singleton class pattern allows data encapsulation regardless of location with respect to compilation-units; it is correctly encapsulated even if it is defined in a file with other classes and functions.

Also it would not in fact emulate the behaviour of the singleton pattern, but merely that of a static object, which is not the same thing. A singleton's lifetime is independent of the life of the process that contains it. The correctly formed singleton is instantiated on first use, whereas static data is instantiated and initialised before main() is started. This may be a problem, if say construction of the object relies on the existence of some other run-time entity. Also the singleton object occupies no memory (other than its static instance pointer) until it is instantiated. It may also be destroyed and re-created at any time, and indeed many times.

Note if you modify your singleton to make the constructor protected rather than private, you can subclass it (and thus easily apply reuse singleton pattern), you can't do that with a static object, or an object with all static members, or functions with file scoped static data, or any other way you may try to get around doing it correctly.

There is nothing wrong with your suggestion per se, just so long as you are aware that it is not a singleton pattern, and lacks it's flexibility.

Clifford
A: 

Personally, I use singletons when I want to have control of when the constructor is executed for the first time.

For example; if I have a singleton for my log-system, the code to open a file for writing is put into the singleton constructur, which is is called like; Logger.instance(); in my startup process. If i'd use a namespace I would have that control.

Viktor Sehr