Implementing a Thread-Safe Singleton with C++11 Using Magic Statics

A couple of years ago I wrote a blogpost on how to write a thread-safe singleton using C++11. That implementation used std::call_once().

However, if your compiler is fully C++11 compliant, and by now, all major compilers are fully compliant, then the best way to implement a singleton is to use a magic static, as follows:

class CSingleton final
	static CSingleton& GetInstance();

	CSingleton() = default;
	~CSingleton() = default;

	CSingleton(const CSingleton&) = delete;
	CSingleton& operator=(const CSingleton&) = delete;
	CSingleton(CSingleton&&) = delete;
	CSingleton& operator=(CSingleton&&) = delete;

CSingleton& CSingleton::GetInstance()
	static CSingleton instance;
	return instance;

The most important change is the implementation of GetInstance() which now contains a local static variable (magic static). C++11 guarantees that this will be initialized in a thread-safe way.
I have now also marked the class as final, made the destructor non-virtual and private, and deleted the move constructor and move assignment operator.


5 Comments so far »

  1. Akin Ocal said,

    Wrote on August 28, 2017 @ 12:45 pm

    Hi Marc,

    One note that is MSVC is an exception in this case :

  2. Marc Gregoire said,

    Wrote on August 29, 2017 @ 9:29 am

    Hi Akin,

    The article you mention is from 2004.
    In the meantime, Visual C++ has supported Magic Statics since VC++2015, see here:

  3. Akin Ocal said,

    Wrote on August 29, 2017 @ 6:40 pm

    Ah wasn`t aware of that, so it appears as it is ok to use the thread safe static starting from VS2015.

    Thanks for the link

  4. Han said,

    Wrote on September 18, 2019 @ 1:37 am

    can I ask how to create a instance? I tried to call GetInstance() and got compile error.

  5. Marc Gregoire said,

    Wrote on September 22, 2019 @ 5:31 pm

    GetInstance() should work. Can you post your code and the exact error message?

Comment RSS · TrackBack URI

Leave a Comment

Name: (Required)

E-mail: (Required)