There are at least two functional reasons:
1. Protection against future instantiation of the type in question.
2. Protection against rewrite of the global reference.
With a singleton you can keep developers not up on the API from using it
incorrectly. You can keep them from instantiating a type that must
never be instantiated again. You can also keep them from attempting to
replace the variable through either simply blocking that access or
providing appropriate filters to do so.
The singleton is not a global variable. The singleton ENCAPSULATES a
global variable. More encapsulation is always good. You can always
crack open a singleton by exposing its creational interface. You can
change it's internal behavior such that it's actually a conglomeration
of many objects without any client knowing this. Hiding a global
variable is much more difficult.
Yet more interesting is a little pattern I found that I'm sure others
have as well, the use of pimpl to implement singleton. The object uses
the handle/body (pimpl) idiom but the impl is actually a singleton.
Clients who create instances of the class itself have no knowledge that
they're all working with the same 'object'. This is something you could
do, in theory, with global variables but ICK!
That is interesting, although I'm having trouble imagining a situation
I'd use it in.
The problem with singleton is that people abuse it, as can be seen by
the fact that very few participating in this discussion seem to
understand its intended purpose: enforcing a creational policy.
My use of it seems a little bit unusual... maybe there is a better
way. Basically I have something like this (although I've greatly
simplified):
=== begin example ===
// Some base class.
class ThingBase {
...
};
// Some default implementation of ThingBase.
class DefaultThing : public ThingBase {
public:
static DefaultThing * getInstance ();
private:
DefaultThing (...);
};
// And many other ThingBase derived classes exist.
// SomeClass uses a ThingBase:
class SomeClass {
public:
// This takes a ThingBase, but NULL can be specified to
// use the default implementation.
SomeClass (ThingBase *thing, ...)
: thing_(thing ? thing : DefaultThing::getInstance())
{
}
private:
ThingBase *thing_;
};
=== end example ===
Like I said, I simplified -- there are other ways to construct a
SomeClass with a default "thing" besides just passing NULL to a
constructor.
What I am trying to do here is avoid having to instantiate a new
DefaultThing in SomeClass if the default was to be used, because then
I would have to keep track of whether or not I actually did that, and
add some logic to delete "thing_" in ~SomeClass() if so. I do this
same thing in other places besides SomeClass, and using a single
instance of DefaultThing simplified things all around. The
implementation details of DefaultThing do make it safe to use a single
instance from everywhere, by the way.
I had also considered simply having a static DefaultThing instance in
SomeClass (and other static instances in other classes besides
SomeClass). It's not a problem to instantiate more than one
DefaultThing, the only requirement is a simple way to eliminate clean
up logic.
But... I was confused (and still am a little) about static
initialization order and wasn't sure if that was a good idea or not.
I'm trying to impose as little usage requirements as possible because
eventually other developers are going to have to work with this, and I
want to minimize the amount of slapping-people-around-when-they-don't-
read-my-documentation that I have to do -- assuming I'm still even
working on the project.
Thanks,
Jason