I know the following is a thread-safe way to implement a singleton in C++11:
Foo* getInst()
{
static Foo* inst = new Foo(...);
return inst;
}
Static variables are NOT allocated on the stack. In the first variant you have a static pointer (a global variable) initialized with a memory obtained from the heap, while in the second one you have whole static object.
Both versions use internal compiler guards (namely __cxa_guard_acquire()
and __cxa_guard_release()
, which are functionally equivalent to mutex::lock()
and mutex::unlock()
) to ensure serialized access to a special variable that tells whether or not your global instances are already initialized or not.
Your code:
Foo& getInst()
{
static Foo inst(...);
return inst;
}
will actually look like that after the compilation:
Foo& getInst()
{
static Foo inst; // uninitialized - zero
static guard instGuard; // zero
if (is_initialized(instGuard) == false)
{
__cxa_guard_acquire(instGuard);
// do the initialization here - calls Foo constructor
set_initialized(instGuard);
__cxa_guard_release(instGuard);
}
return inst;
}
So both of your exampes are thread safe.