Tutorial :Singleton - Why use classes?



Question:

Just the other day I have seen code that uses the so called singleton pattern. Meaning something along the lines of

class MySingleton{  public:      void foo() { ... }      static MySingleton&get_instance(){          static MySingleton singleton;          return singleton      }  private:      MySingleton(){ ... }      ~MySingleton(){ ... }      int bar;  };  

I do see why one would want to do that:

  • Make the instance globally accessible.
  • Make sure that there is never more than one instance of that class.

However I do not see why this way of doing things is superior to a couple of free functions. The way I'd implement it is to put

namespace some_name{      void foo();  }  

in the header and

namespace some_name{      void foo(){          ...      }  }  

in the implementation file. If I need initialization and/or cleanup I either add a couple of functions that must be explicitly called or I add

namespace{      class Dummy{          Dummy(){ ... }          ~Dummy(){ ... }      }dummy;  }  

into the implementation file.

I know that this is from a semantic point of view a singleton, however I see the first variant used far more often in C++ Code than the second. Why? I consider the second version to be slightly superior, so I asking myself if I'm missing something obvious.

  • The second version is simpler to implement and less error prone. In the first variant the private copy constructor is missing on purpose to demonstrate this. In the second variant there is no way to do this error.
  • Implementation and interface are better separated in the second version. In the first all private members must be declared in the header. This has the advantage that you can rewrite the implementation from scratch and don't even need to recompile anything that uses the singleton. When using the first variant it is very likely that you have to recompile all user code even when only changing slight implementation details.
  • Implementation details are hidden in both cases. In the first variant using private and in the second variant using unnamed namespaces.

Can you please explain me why everybody uses the first variant? I don't see a single advantage over the good old way of doing things in C.


Solution:1

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.


Solution:2

does this help?

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.


Solution:3

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.


Solution:4

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.


Solution:5

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.


Solution:6

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.


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »