Library/C++/Creating a Singleton using C++0x

From Athile

Jump to:navigation, search
This page is a work-in-progress. It is not yet complete.
It may contain inaccurate, incorrect information. Use at your own risk.

Overview

A Singleton design pattern g is a common, well-known design pattern g. This article briefly explains a generic way to make a class into a Singleton using C++0x g classes std::shared_ptr<> g, std::weak_ptr<> g, and a helper method.

The basic idea is this:

Implementation

In your singleton class:

  1. Add a public acquire() method that calls a template function helper (will be shown in a moment). This must return a std::shared_ptr<> for the automatic release to occur properly.
  2. Add friend declaration to the template function to ensure only it has access to the protected constructor and destructor
  3. Add protected/private static singleton object as a std::weak_ptr<>
  4. Add protected/private constructor / destructor declarations


    class Engine
    {
    public:
        //! Acquire the Singleton for the Engine
        static std::shared_ptr<T> acquire() { return detail::acquireSingleton<Engine>(s_wpEngine); }
 
        ...
 
    protected:
        template <typename T> friend std::shared_ptr<T> detail::acquireSingleton (std::weak_ptr<T>&);
        static std::weak_ptr<Engine> s_wpEngine;
 
        Engine();
        ~Engine(); 
 
        ...
    };

That is all that is required for each Singleton class. Now for the shared acquireSingleton template which does most of the work.

Make note of the following:


 
        template <typename Klass>
        std::shared_ptr<Klass> 
        acquireSingleton (std::weak_ptr<Klass>& global_wptr)
        {
            // DeleteFunctor is used to expose access to the destructor to shared_ptr
            // but no one else.  
            // See: http://beta.boost.org/doc/libs/1_42_0/libs/smart_ptr/sp_techniques.html
            struct DeleteFunctor
            { 
                void operator()(Klass* p) { delete p; }
            }; 
 
            std::shared_ptr<Klass> sp( global_wptr.lock() );
            if (!sp.get())
            {
                sp.reset( new Klass, DeleteFunctor() );
                global_wptr = sp;
            }  
            return sp;
        }
Navigation
Toolbox