
Anthony Williams wrote:
Tobias Schwinger <tschwinger@isonews2.com> writes:
thanks for your review.
You're welcome.
Anthony Williams wrote:
I don't think this is at all useful. People should not be encouraged to use singletons, as there is already a tendency towards overuse. In most circumstances, singletons are a poor design choice, so there is little requirement for their use. Any design that's picked carelessly is poor or just at best a fluke.
Can't argue with that!
Having a framework internally use some Singletons can greatly simplify its use.
Possibly, but I don't think they're needed even then. If they're an implementation detail of the framework, you don't need to make things a singleton in order to ensure there is only one instance --- just create one.
What's so different between "using a Singleton" and "just creating one"? In fact, "just creating one" should be exactly what this library is all about ;-).
Exposing a singleton to a user provides more flexibility than exposing a static interface (and can also improve performance).
I don't see how. You can easily rewrite a static interface to use a singleton internally. Having a framework provide the user with a (reference-counted) pointer to an interface suitably hides all the details.
Yes, rewriting the code that uses the interface to use a non-static one seems less trivial of a task, however.
A "tendency towards overuse" is not a good reason to reject a library, as it won't stop overuse and encourages more half-baked solutions that are written in a hurry.
It is better to educate people in better ways of doing things (and provide tools to make those things easy) than enable them to easily do something that's generally a bad idea.
Without promoting Singletons people will use globals. And they will use more globals than they would use Singletons (especially in C++ because without we can't be sure initialization code is run if we're inside a dynamic library, so we probably end up using POD typed globals).
* What is your evaluation of the design? * What is your evaluation of the implementation? The design mixes several independent issues --- ensuring there is only one instance of a class and avoiding initialization order problems with on-demand initialization for starters.
A simple wrapper class that allows for on-demand initialization, would be useful. Conflating that with "there shall be at most one instance" is not.
Again, allowing for a preferred destruction sequence of objects with such on-demand initialization might also be useful, but does not belong with the one-instance constraint. What is the point in managing construction order without static context?
Sometimes there are uses for globals. In those cases, it is important to manage the construction and destruction order, independent of how many instances of any given class there may be.
OK. With a Singleton, the type serves as the key to access the global which I personally find quite elegant. A singleton can easily hold several instances of any other class, if a container is put into it. Further you can use multiple-inheritance to instantiate many singletons with a common subobject at compile time. So what are the alternatives (concrete interface proposals, please)?
What is the point of having more than one instance of a class that lives in static context -- and how would it be captured syntacticly?
I can imagine a use for having lots of instances of boost::mutex at global scope --- each mutex protects a different thing. You don't need to capture the syntactic idea "there may be more than one of this class" --- that is the base level assumption.
Interestingly, you show us that in this very case the things you try to protect should be 'mutexed_singleton'S to avoid namespace pollution and to add clarity ;-).
thread_specific_singleton is overly complex for what should just amount to a simple use of thread_specific_ptr. It uses 'thread_specific_ptr' and has additional responsibilities.
Could you be more specific, please?
thread_specific_ptr on its own provides for one instance of an object per thread. I disagree that a class should impose that there is one and only one instance per thread (and no globals) --- this is a decision for the user of a class, not for the class itself. As I understand from the docs, the additional responsibility is the destruction order management. I agree this is a useful facility to provide, and think it is independent of the singleton nature of the classes, so should be separated into its own class.
The responsibilities of a Singleton. Citing another post (sorry for the redundancy -- I think I'll add a brushed-up version of this list to the documentation).
I've written code that used singletons (and regretted it later), and used code that other people have written containing singletons. So you should like this library: The design chosen allows you to easily substitute Singletons with Smart Pointers.
I disagree. If people know something is a singleton, then they don't bother keep the reference around, as they can get it again later. Changing code that does that to code that can use a passed in instance requires adding parameters and/or storing references. You can't just change uses of a singleton to use a smart pointer instead without thought to *how* it's being used.