From: Jason Hise (chaos_at_[hidden])
Date: 2005-01-07 13:51:51
I realize now that there is little interest in considering my library
for Boost over an adaptation of the Loki library... however, even if my
implementation is not under consideration, would someone be willing to
explain what advantages Loki offers over it?
Dave Handley wrote:
> 1) Wouldn't it be better to use CRTP than the rather strange usage
> syntax that Loki uses with a typedef and a requirement to make the
> constructors/destructors private? It is remarkably easy if you are
> not familiar with the Singleton implementation in Loki to make your
> constructors/destructors public by mistake and then use them, whereas
> a CRTP solution could make the base constructors/destructors protected.
With my implementation it is perfectly safe for client code to make
public constructors and destructors and not have to worry about the
class being used the wrong way, because the inheritance method I used
makes it pure virtual.
> 2) There are probably some more options that need to be included,
> for example making a Singleton be capable of destroying/recreating
> during the run of a program. Consider a singleton that is managing a
> print queue. For some reason all the printers go off-line, there is a
> potential for memory optimisation by closing down the print queue. If
> printers come back on line the print queue could come back on line -
> but that isn't possible (as far as I know) with Loki.
With my revised usage of dependencies, the singleton would be destroyed
when there were no dependencies left and recreated when new ones were
added. If client code wants to ensure that the singleton's life is not
interrupted, they could add a dependency in main, or even add a
static/global dependency to ensure that the lifetime extends beyond main
if that feature is desired. Using dependencies also can ensure that
singletons which rely on each other are always created and destroyed in
the right order.
Again, I am unfamiliar with Loki, so I am sure that there are
considerations that it handles of which I am unaware. I would just like
to learn what these considerations are so that I might grow as a
programmer, and learn through improving my own implementation. Thanks
Link posted for reference:
Notice: There was a message that I posted two days ago that seemed to
have been lost... it is probably obsolete and repetitive now, but it is
attached should anyone care to read it.
Dave Handley wrote:
>> Ordering of Singletons is, in my opinion, one of the most important issues with Singletons. It is almost
certainly insufficient in most applications to create in a specific order, and delete in reverse order.
One reason for this is start-up performance - you don't want every Singleton to have to create at startup
(necessarily). Another reason can be memory efficiency. Loki again provides a number of policies
including a Phoenix Singleton and a Longevity managed singleton. I personally tend to use Longevity
managed singletons linked to the at_exit function. Nevertheless, there are some additional things that
I would like to see - for example, a phoenix singleton that could be created and destroyed more than once
during a program run could be useful - either explicitly or even if not used for a while. Also, allowing
thread-safety as an option is also crucial.
The way that my design works is to use reference counting in the form
of dependency objects, which create the singleton when the first
dependency is constructed and destroy the singleton when the last
dependency is destroyed. If a singleton A owns a dependency on
singleton B, that dependency lifetime will be greater than the
lifetime of A itself, meaning that B will exist for the duration of
The only property of my singleton that forces it to be constructed
before main and destructed after is the existence of a static
dependency in the singleton class to itself. If I removed this static
dependency, it would allow for singletons that could be created and
destroyed any number of times, and lifetime would be completely
controlled by the scope at which the dependencies lived.
Implementing this change would make it possible for GetInst to fail,
when it would be more desirable to have GetInst somehow utilize a
dependency itself. Perhaps I could enable this by having GetInst
return a type of smart pointer, which would own a singleton dependency
as well as pointing to the singleton object. Thoughts / suggestions?
I have no experience in dealing with thread safety. Would ensuring
thread safety require that the singleton have access to a threading
library, or would it be possible to just write the code more carefully
to ensure safety, similar to writing exception safe code?
In addition, I have no familiarity with the other design patterns you
mentioned, nor with Loki. I learned about the singleton concept
through a friend and thought that it made for an interesting
challenge. I just ordered Modern C++ Design, so hopefully I can
familiarize myself with these topics in the near future.
For reference, I will leave a link to the code below:
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk