|
Boost : |
From: Gennadiy E. Rozental (rogeeff_at_[hidden])
Date: 2001-11-15 20:09:08
--- In boost_at_y..., scleary_at_j... wrote:
> > From: Mattias Flodin [mailto:flodin_at_c...]
> >
> > IMHO policies are needed primarily because reality is not so
theoretical
> > as one would like it to be.
>
> Considering 'real' situations, then:
>
> > You may run into problems with lifetime when
> > you try to have several singletons that depend on each other.
>
> Two singletons, A and B, where A depends on B and B depends on A is
an
> impossible situation. The dependency graph for singletons is a
DAG, and
> follows the same lifetime rules as objects of static duration.
Therefore,
> one solution fits every 'real' problem.
I do not think that situation when with several dependent singleton
is not impossible. To amke them to be destroyed in proper order you
need to make sure that tay are constructed in proper order. And it is
questionable what is easier: make them constracted in proper order or
having managable mechanism to be able to set destruction order
(former need to be solved every time, when latter is written ones and
reused)
>
> > There are
> > efficiency concerns, such as avoiding mutex locks on every access
if your
> > code does not need to be thread safe.
>
> Providing locking for "every access" wouldn't actually gain
anything -- the
> lock would be released when the pointer is returned. Therefore, one
> solution (only lock on the *first* access, using the double-checked
locking
> idiom) fits every 'real' problem -- you only have the overhead of
one lock
> per singleton in your program.
What if you have to limit simultaniose access to singleton? Or what
if you want each thread to have separate copy of singleton? Or what
if from performance prospective you what to substitute your one-
instance singleton with fixed-size pool based one and you will need
to wait till instance become available?
>
> > And there's the issue of
> > initialization parameters to consider. I'd say a singleton is a
singleton
> > even if it needs parameters (such as log file name) for
initialization.
>
> Yes, now here's something that I've thought of several times, not
sure if I
> needed to include it or not. I've decided not, following the
thoughts:
>
> A singleton with parameters must get its parameter values from
somewhere.
> This "somewhere" may be hard-coded or dynamic -- where "dynamic"
may be
> anything from a calculated value to a configuration file.
> If "somewhere" is hard-coded, instead of hard-coding it multiple
times at
> the call to instance(), create a derived class that hard-codes the
base
> class constructor parameters.
> If "somewhere" is dynamic, then that dynamic code can either be in
a derived
> class, as above, or in another singleton.
>
> Therefore, one solution (default-construct only) fits every 'real'
problem.
I do not follow. What if I have a singleton which read it's
configuration from the file, passed as command line argument?
>
>
> I read not too long ago in an article (I can't remember where!)
about code
> re-use being so overly hyped that object-oriented programmers would
add
> function after function to their code hierarchies until they had a
re-usable
> class -- that no-one wanted to use! :)
> In generic programming, the same phenomenon occurs when well-meaning
> programmers add requirements (often optional) to their concepts.
> And in generative programming, similar behaviour is found when well-
meaning
> programmers add policies.
>
> In each case, the interface (be it an abstract base class, a
concept, or a
> type generator) becomes complicated quickly; but ease of
maintenance and
> ease of use (*especially* for new users) decreases quickly, with
only a
> small amount of added flexibility or capability.
>
> The article concluded by stating that some programmers *do* produce
> re-usable code. But they do so by *preventing* complication of
their
> interfaces. Essentially, they do what's necessary, and nothing
more.
>
> Look at the smart pointer classes -- in my code, I have a header
that simply
> imports the boost smart pointers and STL smart pointer, and adds
two of my
> own:
> scoped_ptr
> scoped_array
> auto_ptr
> auto_array [1]
> shared_ptr
> shared_array
> mt_shared_ptr [1]
>
> There has been some talk on this list about using policy classes,
and having
> a single smart pointer generator. We could allow different
deallocation
> mechanisms, different sharing capabilities, hooks for user
callbacks... But
> how many users would ever use them? We'd be adding a lot of
complexity with
> a small payback.
Instead you proposing create new class using copy-paste every time
you need slightly different functionallity. You need debug-like
scoped_ptr which log every object creation/destruction - new class.
You need smart_ptr with one performance characteristics - one class,
another - different class. You need smart_ptr with one
sinchronization policy - one class, another - different class. You
need auto handle for you resource - one more class.
I prefer ONE powefull enough template that can generate all of these
variation just by mean of providing proper policy arguments.
>
> Just my 2 cents. Wait -- I'm probably up to a good dollar by
now! :)
>
> -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