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.
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... |