Thread-safe lazy singleton template class

This class is a thread-safe lazy singleton template class, which can be used during static initialization or anytime after. This class displays the powerful features of the boost::once class. The boost::once class is thread-safe and allows one to call a function exactly one time.

Notes:

- If T's constructor throws, instance() will return a null reference. - If your singleton class manages resources, you may provide a public destructor, and it will be called when the instance of your singleton class is out of scoped (see scoped_ptr docs).

By Port4l with contributions by nobody yet.

Recipe source code

#ifndef SINGLETON_HPP
#define SINGLETON_HPP

#include <boost/utility.hpp>
#include <boost/thread/once.hpp>
#include <boost/scoped_ptr.hpp>

// Warning: If T's constructor throws, instance() will return a null reference.

namespace Templates
{

template<class T>

class Singleton : private boost::noncopyable
{

public:
    static T& instance()
    {
        boost::call_once(init, flag);
        return *t;
    }

    static void init() // never throws
    {
        t.reset(new T());
    }

protected:
    ~Singleton() {}
     Singleton() {}

private:
     static boost::scoped_ptr<T> t;
     static boost::once_flag flag;

};

}

template<class T> boost::scoped_ptr<T> Templates::Singleton<T>::t(0);
template<class T> boost::once_flag Templates::Singleton<T>::flag = BOOST_ONCE_INIT;

#endif




How to use this class?

myclass.hpp

#ifndef MYCLASS_HPP
#define MYCLASS_HPP

#include "singleton.hpp"

using namespace Templates;

class MyClass : public Singleton<MyClass>
{ 

friend class Singleton<MyClass>;

public:

     void doSomething() { std::cout << "Something"; }

private:

     MyClass();

};

#endif

main.cpp

#include <boost/thread/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <iostream>

#include “myclass.hpp”

void test()
{ 
   MyClass::instance().doSomething(); 
}

int main(int argc, char* []argv) 
{    
    boost::thread thread1(&test);    
    boost::thread thread2(&test);    
    thread1.join();    
    thread2.join();    
    return 0; 
}

This is not an official Boost site. For more information on Boost please see Boost.org.