Boost logo

Boost :

From: Gennadiy E. Rozental (rogeeff_at_[hidden])
Date: 2001-11-13 21:42:27


--- In boost_at_y..., "Rainer Deyke" <root_at_r...> wrote:
> ----- Original Message -----
> From: "Gennadiy E. Rozental" <rogeeff_at_m...>
> To: <boost_at_y...>
> Sent: Tuesday, November 13, 2001 1:22 PM
> Subject: [boost] Re: Work in progress list? And how about a
singleton?
>
>
> > I am also looking in this direction for some time now. Here what I
> > think we need to make a really reusable singleton. The singleton
> > design should be able to adopt following design desision made by
user:
>
> This looks like a backwards approach: you don't start with a
problem that
> you're trying to solve, but an abstraction which may or may not
prove useful
> in solving real problems.

In my expirience need for the singleton abstraction is encountered
rather frequently. So I think I have some original problem that I
need to find a solution for.

> When I need global state that is sensitive to
> creation order in my program, I tend to do something like this:
>
> std::vector<std::string>& get_strings()
> {
> static std::vector<std::string> strings;
> return strings;
> }
>
> The problem is thus solved in six lines without the need for a
singleton
> class and its single instance. I think there is a real danger that
an
> overly abstract design makes it harder to configure and use your
singleton
> class than to write a specific singleton from scratch.

This is simpliest singleton (decision 1.b, 2.b, 3.a, 4.c, 5.a, 6.a,
7.a, 8.a ). Another issue is that you allow instantiating of
singleton class by anybody, which is supposed to be prohibited (this
is one of the reason to use singleton). By this means you can't
implement non default constructable singleton and so on. You could
take a look in my comments in
http://groups.yahoo.com/group/boost/message/19949

>
> > 1. Way the singleton is instantiated. Possible variations:
> > a. Static pointer as class member
> > b. Static pointer as local variable in some method
> > c. static variable as class member
> > d. Static variable as local variable in some method
> > e. Static variable in implementation file
> > g. Variable in thread-specific storage
> > and couple more
>
> Excepting the last one, which solves an entirely different problem,
what
> difference does it make? The user cares about functionality, not
> implementation.

This is one of the desing decisions that the singleton design should
be able to answer depends on user requirenments. User involvement
could be implicit.

>
> > 2. When singleton is created:
> > a. automatically before main
> > b. automatically in static memory at the point of first access
> > d. automatically in dynamic memory at the point of first access
> > c. mannually by user
> > and couple more
>
> Several issues here.
>
> - Sometimes a global resource has a specific lifetime. This is
easily
> modeled through a pointer.
>
> boost::scoped_ptr<A> a = 0;
>
> int main()
> {
> a.reset(new A);
> // something else
> a.reset();
> }
>
> Sometimes the lifetime of such a global resource is tied to some
other
> object, in which something like this would work:
>
> class A;
> A *a = 0;
> class A {
> public:
> A() { assert(!a); a = this; }
> ~A() { a = 0; }
> };
>
> int main()
> {
> A shared_a;
> // something else
> }
>
> - Sometimes a global resource does not have a specific lifetime,
it just
> needs to be there when I need it. In this case any creation time
other than
> first point of access doesn't really make sense. I also don't see
any
> significant commonality between this type of shared resource and
the other
> type, so I would not attempt a single class that handles both.

Well, I see some commonality and trying to use generative power of
C++ templates to create two different classes from the same source,
while all differences are factored into some policy/traits classes.

>
> - If the object is created before 'main', then any exceptions
thrown during
> construction cannot be caught.

Why, can't you use function try block? In general if critical
resource fail to initialize, program should not proceed. Moreover it
could be one of the reason to prefer automatically created singleton.
Also singleton is simple pattern and reason to prefer one decision
over another could be just a matter of convenience.

>
> > 4. Way the singleton is accessed
> > a. by pointer
> > b. by const pointer
> > c. by reference
> > d. by const reference
>
> By pointer if the pointer could be a null pointer to indicate the
object is
> not yet created or already destroyed. By reference otherwise.

By const pointer/reference if you don't want give an access to non
const members.

>
> > e. counting reference
>
> I assume this is in support of 5c below?
>
> > 5. Way the singleton is destroyed
> > a. automatically after exit from main
>
> This is the only one that makes sense for global resources that are
created
> on point of first access.
>
> > b. manually by user
>
> This is the only one that makes sense if the user manually creates
it.

No. You can create singleton at point of first access and then
destroy it when you think you do not need it anymore. And vice versa
You could create singleton manually and do not want to care about
when and how it will be destroyed.

>
> > c automatically if not used
>
> This seems to be another different type of global resource, not
necessarily
> related to the others.

I do not see that much difference. The key features of singleton is
an ability to provide an acess to a single object of a class that
can't be instantiated by other means.
>
> > 6. How to manage destruction several coworking singletons
>
> Inverse order of construction.

Sorry for bad example in other posting. Consider following one, even
simplier: A need global log object L for creating and destruction. So
order of creation A, L. Automatic order of destruction L, A. When A
destructed L already gone.

>
> > 8. Number of times singleton could be instantiated
> > a. One time
>
> This is automatically the case if it is created on point of first
access and
> remains in existence until exit from main.
>
> > b. Many times - phoenix singleton
>
> This is automatically the case if it's lifetime is controlled by
the user.

No. Possible scenario: you somehow(manually or automatically) create
singleton then destroy it, somehow create it then destroy it and so
on. On other hand you may want to prevent singleton from being able
to recreate. How singleton is created is not relevant.

>
>
> --
> Rainer Deyke (root_at_r...)
> Shareware computer games -
http://rainerdeyke.com
> "In ihren Reihen zu stehen heisst unter Feinden zu kaempfen" -
Abigor


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk