首先看看boost 的单例模式
@ boost/thread/detail/singleton.hpp
template <class T>
class singleton : private T
{
private:
singleton();
~singleton();
public:
static T &instance();
};
template <class T>
inline singleton<T>::singleton()
{
/* no-op */
}
template <class T>
inline singleton<T>::~singleton()
{
/* no-op */
}
template <class T>
/*static*/ T &singleton<T>::instance()
{
// function-local static to force this to work correctly at static
// initialization time.
static singleton<T> s_oT;
return(s_oT);
}
单例在首次调用访问时产生 非线程安全
@ boost/container/detail/singleton.hpp
// T must be: no-throw default constructible and no-throw destructible
template <typename T>
struct singleton_default
{
private:
struct object_creator
{
// This constructor does nothing more than ensure that instance()
// is called before main() begins, thus creating the static
// T object before multithreading race issues can come up.
object_creator() { singleton_default<T>::instance(); }
inline void do_nothing() const { }
};
static object_creator create_object;
singleton_default();
public:
typedef T object_type;
// If, at any point (in user code), singleton_default<T>::instance()
// is called, then the following function is instantiated.
static object_type & instance()
{
// This is the object that we return a reference to.
// It is guaranteed to be created before main() begins because of
// the next line.
static object_type obj;
// The following line does nothing else than force the instantiation
// of singleton_default<T>::create_object, whose constructor is
// called before main() begins.
create_object.do_nothing();
return obj;
}
};
template <typename T>
typename singleton_default<T>::object_creator
singleton_default<T>::create_object;
重要的是这句:
// The following line does nothing else than force the instantiation
// of singleton_default<T>::create_object, whose constructor is
// called before main() begins.
保证单例在main() 之前生成
类似的设计在boost还有,
再来一个陈硕的 singleton
template<typename T>
class Singleton : boost::noncopyable
{
public:
static T& instance()
{
pthread_once(&ponce_, &Singleton::init);
assert(value_ != NULL);
return *value_;
}
private:
Singleton();
~Singleton();
static void init()
{
value_ = new T();
if (!detail::has_no_destroy<T>::value)
{
::atexit(destroy);
}
}
static void destroy()
{
typedef char T_must_be_complete_type[sizeof(T) == 0 ? -1 : 1];
T_must_be_complete_type dummy; (void) dummy;
delete value_;
value_ = NULL;
}
private:
static pthread_once_t ponce_;
static T* value_;
};
template<typename T>
pthread_once_t Singleton<T>::ponce_ = PTHREAD_ONCE_INIT;
template<typename T>
T* Singleton<T>::value_ = NULL;
使用pthread_once 保证init 只执行一次
c++ 11 的 call_once
template< class Function, class... Args >
void call_once ( std::once_flag& flag, Function&& f, Args&& args... );
参数解析Parameters:
flag - an object, for which exactly one function gets executed
f - 需要被调用的函数
args... - 传递给函数f的参数(可以多个)
返回值为 (none)
抛出异常
std::system_error if any condition prevents calls to call_once from executing as specified any exception thrown by f
使用 所以我们能使用 call_once 函数实现一个 跨平台的singleton
首先拷贝 boost nocopyable
class noncopyable
{
protected:
noncopyable() {}
~noncopyable() {}
private: // emphasize the following members are private
noncopyable(const noncopyable&);
const noncopyable& operator=(const noncopyable&);
};
template<typename T>
class Singleton : public noncopyable
{
public:
static T& instance()
{
call_once(ponce_, &Singleton::init);
return *value_;
}
private:
static void init()
{
value_ = new T();
}
private:
static std::once_flag ponce_;
static T* value_;
};
template<typename T>
std::once_flag Singleton<T>::ponce_ ;
template<typename T>
T* Singleton<T>::value_ = nullptr;