toast singleton


Detailed Description

Introduction

When to Use

Using the library

Introduction

toast::singleton_helper helps separate your class's logic from the supporting code that turns it into a singleton. It also makes it painless to transition from a program-wide singleton to a thread-specific multiton. Finally, it initializes lazily, saving your program startup time, and does so in a threadsafe way. Most singleton implementations claim to be threadsafe but in fact are not. Notably, the double checked locking strategy used by most implementations is broken (as are solutions that use the volatile keyword).

When to Use

Many singletons are glorified globals. You already know why globals are bad. Making a global a singleton might make it slightly safer in some senses, but it doesn't eliminate any of the problems of coupling that globals introduce. Don't use singletons globally unless you have an excuse good enough to justify the use of a global.

Instead hide your singletons as much as possible. Preferably in nameless namespaces deep in the source files of your module. Well ok, that might be too deep. You really only need one singleton per library at the most. Especially if they're using thread specific storage or some other sparse resource. So perhaps a private header file in that case, only accessible by source files for that library. If it's not clear, this implies that there is no public interface to your singleton! Singletons should never be part of an API, they should be an implementation detail only.

If you are working on a legacy application, transitioning its singletons to use singleton_helper instead will make converting your app to be multithreaded easier, since switching over a thread specific multiton will simply be a change in template parameters. If you ever need your singleton to become a real object, there will also be less work to do because singleton_helper has already kept the singleton-implementation logic separate from your core class.

Using the library

Let's say your library needs an int to share with its components. singleton_helper<int> is not an appropriate choice, although it would appear to work. That is until there was another module that needed to share an int amongst it's components. Instead wrap the data you need singleton'ed into a struct or class (thus making the type unique, remember templates only get instantiated once per type). This will make it easier to keep the number of singletons down to one per library anyway.

singleton_helper is different from other singleton solutions in that if you want a singleton class MyClass, you don't write MyClass any differently than a normal class; you don't need to make all of the methods static or provide your own instance method. You simply call singleton_helper<MyClass>::get() to access the singleton copy of your class.

singleton_helper in fact takes 3 template parameters, but has sensible defaults for the latter two.

HolderType specifies how you want singleton_helper to store the instance of your singleton class internally. It defaults to using a boost optional, which will make sure your class is lazily initialized, though you could also use a MyClass* for the same effect. If you use a plan T directly, then the object will be constructed at static initialization.

The FactoryType parameter specifies how singleton_helper should internally construct the instance of your class. By default it will just call the class's default constructor (the default_factory<T>).

To make your singleton into a thread specific multiton, use boost::thread_specific_ptr<T> as your HolderType and boost::thread_specific_factory<T> as your FactoryType.


Files

file  singleton.hpp
 singleton.hpp contains the singleton_helper template class.

Classes

struct  toast::default_factory< T >
 This factory creates T with its default constructor. More...
class  toast::global_factory< T >
 This factory creates T with any toast::typed_factory<T> you like. More...
class  toast::thread_specific_factory< T >
 This factory creates T with any toast::typed_factory<T> you like. More...
class  toast::singleton_helper< T, HolderType, FactoryType, Enable >
 This helper deals with all the accounting details of properly managing a singleton. More...


SourceForge.net Logo