Re: Singletons
Am 21.11.2012 21:56, schrieb fmatthew5876:
Whenever we talk about singletons, people always want to make a
class. One often cited example is some variant of this:
lass CMySingleton
{
public:
static CMySingleton& Instance()
{
static CMySingleton singleton;
return singleton;
}
// Other non-static member functions
private:
CMySingleton() {} // Private
constructor
~CMySingleton() {}
CMySingleton(const CMySingleton&); // Prevent
copy-construction
CMySingleton& operator=(const CMySingleton&); // Prevent
assignment
};
My question is why do people get locked into thinking that the
singleton must be a class?
I think that follows naturally from the fact that all other types can be
copied, so there is no real compile-time protection for a singleton int
or a singleton enumeration.
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. 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 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.
The safety belt added by the standard was carefully designed so
that the overhead can be very small, as outlined in
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2148.html
I hope (but cannot say for sure) that you are observing a QoI issue here.
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
}
Now I can control when the singleton gets initialized and
destroyed. In addition I can also hide the global state of the
singleton in its cpp file and I get to decide whether its heap
allocated or just placed in global memory.
Your thoughts?
So you suggest that everyone who uses your singleton is supposed to
call the init function? The advantage of a singleton is to hide such
internal issues. I also don't see how you can compile-time enforce the
essential invariant of a singleton - namely that only one object of
type X exists.
Further, I don't see why your first variant shouldn't also allow for
hiding the allocation details - there is no requirement that Instance
is *defined* within the class definition.
Just my 2 Euro cents & Greetings from Bremen,
Daniel Kr?gler
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]