From: Mattias Flodin (flodin_at_[hidden])
Date: 2001-11-13 15:30:36


Yes, I've been looking at your singleton now and it is certainly very
interesting - I seems a bit of a shame that it would live the rest of its
life in a 'detail' directory. :)

The properties you describe are also very useful, but I do not understand
how you can guarantee the last one; in my observations, the destruction
order of objects in different modules have no guaranteed relation - I
believe this is also stated in the standard. This is one of the main
reasons I see for the need of a user-instantiated singleton: it is
seemingly the only way to completely control construction and destruction
order.

As for the trick in the constructor, it is there to allow constructs such
as:

class B : public A, public singleton<A> { /* ... */ };

In this case, the 'this' pointer that singleton's ctor receives cannot be
directly reinterpreted as a B pointer. The code essentially casts the
number 1 from being a singleton pointer into being a A pointer, in order
to determine the offset of A in relation to its aggregated singleton.
Casting 0 does not work because such a cast is guaranteed never to modify
the pointer, thus I must use 1 for casting and then subtract 1.

/Mattias

On Tue, 13 Nov 2001 scleary_at_[hidden] wrote:

> > How about a singleton class for boost? This is one of the most simple
> > design patters, and can rather easily be implemented using templates. Just
> > as the smart pointer, there may be a need for different variants, to
> > handle the lifetime of the singleton in different ways.
>
> Hmmm, I have a singleton class in pool. Someone on this list recently gave
> me a new idea on how to do it better; I'm planning to do this soon.
>
> My current singleton:
> . Allows access during dynamic initialization (i.e., before main()).
> . Provides thread-safe construction at the time of its first access.
> . Guarantees destruction order: singletons act as objects with static
> duration.
> With the following restriction:
> . Only one thread may be running before main() begins or after main()
> ends.
>
> The new idea I referred to above will remove that restriction, at which
> point I intend to offer the pool singleton class as a generic singleton
> solution.
>
> Question on your code: what exactly are you doing in the constructor?
> singleton()
> {
> assert(instance_==0);
>
> char* p=reinterpret_cast<char*>(this);
> //I don't see how the following line has any effect
> p-=(int)(singleton*)(T*)(1) - 1;
> instance_=reinterpret_cast<T*>(p);
> }
>
> -Steve
>

--
Mattias Flodin <flodin_at_[hidden]>   "A good thing about C++ is that only
Room D418                           friends can access your private parts"
Department of Computing Science
Umeå University
S-901 87 Umeå, Sweden
Note: Any opinions expressed in this mail are personal, and do not
necessarily reflect an official standpoint of Umeå University.