|
Boost : |
From: Gennadiy E. Rozental (rogeeff_at_[hidden])
Date: 2001-11-13 17:35:24
--- In boost_at_y..., scleary_at_j... wrote:
> > Steve, what are your feelings on all this? Seeing as how you
started a
> > singleton class already, do you feel you have the time to
incorporate
> > these things into your design? Or would you rather I began work
on a more
> > general singleton from 'scratch'?
>
> My current singleton would look very different once I remove that
> restriction (by using an exception-neutral equivalent of
boost::call_once).
> We might just want to start from scratch.
>
> Following are some comments on Gennadiy's list of recommended
policies:
>
> > > Here [is] what I think we need to make a really reusable
singleton.
> > > 1. Way the singleton is instantiated
>
> I disagree; this is an implementation detail, except for the last
one
> "variable in thread-specific storage" which I see as a totally
different
> type of object -- not a singleton at all.
Its implementation choises that you will need to be able to switch
between, depends on answer on other questions. For example, if you
want phoenix singleton you can use static variable in method. Or If
you don't want singleton to be created automatically you can't use
static class member. And so on. The idea is to have a set of possible
instantiation Policies to be able to choose proper. It could be that
user will be involved in this decision or could be not.
>
> > > 2. When singleton is created
>
> Do we need all these options? Static vs. dynamic memory is an
> implementation issue. Just have it created at the point of first
access,
> and if the user wants to create it at a certain point (before main
() or any
> other point), just let him call "instance()".
What should I do if I need a signleton that automatically created
before main and automatically destroyed after exit? Do I need to
write additional instantiator class? SOmetime I know when I need the
singleton first time but do not jnow about the last time. So I want
the singleton take care about itself. In other cases I do not want
for any reason the singleton to be created automatically. I do want
to created it first access. BUT! I do not to care when it will be
deleted. It's "automatically in static memory at the point of first
access" case. Or instead I what to delete it myself or I just do not
have a default constructor for singleton. It's "automatically in
dynamic memory at the point of first access". Or I have very special
way for singleton creation that can't be made generic. In this case I
need "manual by user" choise.
>
> > > 3. How singleton is created
>
> I've thought about this a bit, but there's not a "nice" way to pass
> constructor arguments to a singleton (meaning other than in every
call to
> "instance()"). In fact, I can't think of a single case where this
would be
> useful -- a singleton object really can't depend on anything other
than
> other singletons.
What if you do needsuch a way (for example, global Log - need file
name). I think templated constructor could help here. Or some other
way - I do not know yet.
>
> > > 4. Way the singleton is accessed
>
> My simple answer is: by reference; all the other return types can
be derived
> from this. Except one you mention: "counting reference", which I
address
> below.
What if want prevent user from calling non const method?
What if user is used to pointer semantic and want pointer? Do you
want him to write & at every point of access? Counting references
could be used to implement "deleted if not used" idiom for singleton.
Do you know other way?
>
> > > 5. Way the singleton is destroyed
>
> Why would anyone do anything other than destroy objects of static
duration
> (which is what a singleton is) in the reverse order of their
construction?
If I want to be able to release THIS singleton manually I should be
able to get it. If I do not want to care about THIS singleton
destruction it should be done automatically. Deleted if not used is
another choise that should be supported.
>
> > > 6. How to manage destruction [of] several coworking singletons
>
> If A depends on B for construction, and B depends on A for
destruction, I
> consider that a design error.
What if A depends on B and thay both created and destructed
automatically. How you enforce proper ordef of destruction. Look what
Andrei did to handle this (though I don't think that we should rely
on features that are not in standart yet).
>
> > > 7. Synchronization policy: how and what to synchronize
>
> I follow the simple policy of making the singleton construction
thread-safe.
> Singleton access synchronization is left to the user.
Exactly, but singleton should have a hooks to simplify the
synchronization. For example what If I want to allow I thread in a
time to access the singleton, what if no more then 5 threads? Do I
need to write external wrapper to manage this?
Do we need to guard singleton construction from a possible
simultaneous access from different threads?
>
> > > 8. Number of times singleton could be instantiated
>
> I see here a second type of singleton -- one that has a counted
reference
> (from point 4) and could be re-created as necessary. I think this
could be
> a separate singleton template.
Why do I need a counting reference here. What I meant is a singleton
that could be created, deleted, created, deleted and so on. This
decision could affect desision 1.
>
> In conclusion, I don't think we need to support policies that are:
> 1) Easily done by the user (e.g., "&singleton<T>::instance()"
instead of
> defining a policy for the return type)
It could be trait class that can handle a lot of simple decisions.
> 2) Not useful (e.g., whether the underlying object is a static
local in
> some function or a static class member)
What is usefull will become clear at the end of development.
>
> Policies are good, but don't abstract where abstraction isn't
necessary. :)
I agree. We just have different view on what is nessesary.
>
> -Steve
Regards,
Gennadiy.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk