|
Boost : |
From: Gregory Dai (gregory.dai_at_[hidden])
Date: 2007-05-10 00:18:04
On 5/9/07, Joaquín Mª López Muñoz <joaquin_at_[hidden]> wrote:
>
> Gregory Dai ha escrito:
>
> > On 5/8/07, Medland, Thomas M <thomas.medland_at_[hidden]> wrote:
> > >
> > >
> > > Hi,
> > >
> > > I have just moved company and in my old company I used to use a
> > > RogueWave singleton class. I was looking to use the boost singleton
> > > class. However after looking at the implementation I saw there was no
> > > private default copy constructor or assignment operator. Does this
> not
> > > mean that I could create multiple instances of my singleton via
> > > assignment or some other form of copying? I saw some discussion of a
> > > better singleton representation in boost and I was wondering what the
> > > status of this was, and I was also wondering what other people use for
> > > their singletons?
> > >
> > > Thanks
> > > Tom
> >
> > Well, I use the following. It's pretty simple and it works.
>
> [...]
>
> Hello Greg, I think there's a potential problem with your
> static_instantiation
> policy (or at least a limitation in applicability) due to its relying on
> the class
> template static member static_instantiation::holder<T>::instance_s. As
> this
> member is initialized only once (for a given T), the initialization will
> take
> place in some of the translation units, but there's no way to say which
> one,
> and the standard cannot not guarantee that the initialization will occur
> before the first use of static_instantiation::holder<T> if that use
> happens
> at dynamic initialization time.
Thanks for pointing it out, Joaquín. I've not used the static_instantiation
though it's there. I found myself use lazy_instantiation, which is the
default, all the time.
<snip>
You can solve this by combining a Meyers singleton with some static
> initialization
> forcing technique:
>
> class static_instantiation
> {
> template <typename T>
> struct init_forcer
> {
> init_forcer()
> {
> T* p;
> static_instantiation::make<T>(p);
> }
>
> void do_nothing(){}
>
> static init_forcer<T> init_forcer_s;
> };
>
> protected:
> template <typename T>
> static void make(T*& p)
> {
> init_forcer<T>::init_forcer_s.do_nothing();
> static T instance;
> p = &instance;
> }
> };
Isn't this kind of equivalent to the local_static_instantiation (the second
policy)? In general, we use local static storage to avoid static class
member construction, don't we?
In other words, shall we say that the static_instantiation (instantiation
policy) is there for illustration purpose only, not for applications in
production.
template <typename T>
> typename static_instantiation::init_forcer<T>::init_forcer
> static_instantiation::init_forcer<T>::init_forcer::init_forcer_s;
>
> This technique is used for instance by Boost.Pool,
> see boost/pool/detail/singleton.hpp. Hope this helps,
Thanks again.
Greg
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk