Re: Singletons
On 11/21/2012 9:56 PM, fmatthew5876 wrote:
Whenever we talk about singletons, people always want to make a
class. One often cited example is some variant of this:
class CMySingleton ...
Indeed. I'm also curious on why is that, let me know if you find out.
Maybe it's some side effect of GOF -- ther singleton is listed as
creational pattern -- that makes some sense, and fits the overall book
structure -- but the real life usage of singletons is normally NOT about
the cretion, but about just the global access point to the
single(-looking) instance.
In C++ that certainly needs no class whatsoever and is best implemented
using a global free function. That returns either a namespace or a local
static object.
Creation involved in the popular singleton classes (Meyers-,
Alexandrescu-, leaky, ...), are rarely needed, as the overall
application design states the earliest and latest point of legal access.
And without such global design points whatever cute implementation
tricks tend to fall on face.
My question is why do people get locked into thinking that the
singleton must be a class?
When all you have is hammer everything looks like a nail. The old
schools started programming from very primitive blocks (like assembly,
lisp), then introduced plain data and functions then objects, and at the
end, classes to help deal with similar objects.
New schools tend to start with classes, and without bothering to explain
how we got there. May even start with language where you just can not
avoid classes at all.
The problem with the above is first you
can't control when destruction happens, and second, getting a static
object from a function is actually very expensive.
If you need control over destruction you're probably already in trouble.
Certainly if you have a class to manage the whole thing you can deal
with it -- that is the whole idea after all, though the simple
free-function approach can deal with it no worse.
Everytime you call
Instance() the compiler inserts a hidden check to see if the static
object was already initialized. So thats one unneeded branch everytime
you fetch the singleton.
It might be the case. OTOH this layout have the benefit of not ever
creating the object unless it it gets called -- and that you can use it
during static objects' init without getting into trouble. If those
benefits are not used, it's better avoid the local static usage -- and
it can be rearranged anytime without any change of the client code.
It gets much worse though. Because of thread safety, gcc actually
inserts locking code into the Instance() function, meaning not only
are you doing useless branching, but you also have to grab and release
locks.
Are you sure gcc is that bad? it only needs and atomic_flag to check on
the regular path, not a full lock. And that is not much a drag.
Considering the healthy use of singletons in an application, I'd doubt
measurable difference.
Why not free ourselves from the "everything must be objects" mentally
and just use free functions. For example:
namespace singleton {
void init(/*args */);
void shutdown():
//other singleton methods
}
The init/destroy problem lives on the abstract design level, not
connected to the packaging strategy of the implementation.
I certainly agree that "singleton *class*" is mostly bullshit in C++
world, while the singleton objects are best accessed through a function.
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]