因此,在有了C++11后我们可以正确的跨平台的实现DCL模式了,代码如下:
  1 atomic<Widget*> Widget::pInstance{ nullptr };
  2 Widget* Widget::Instance() {
  3     if (pInstance == nullptr) {
  4         lock_guard<mutex> lock{ mutW };
  5         if (pInstance == nullptr) {
  6             pInstance = new Widget();
  7         }
  8     }
  9     return pInstance;
  10 }
  C++11中的atomic类的默认memory_order_seq_cst保证了3、6行代码的正确同步,由于上面的atomic需要一些性能上的损失,因此我们可以写一个优化的版本:
  1 atomic<Widget*> Widget::pInstance{ nullptr };
  2 Widget* Widget::Instance() {
  3     Widget* p = pInstance;
  4     if (p == nullptr) {
  5         lock_guard<mutex> lock{ mutW };
  6         if ((p = pInstance) == nullptr) {
  7             pInstance = p = new Widget();
  8         }
  9     }
  10     return p;
  11 }
  但是,C++委员会考虑到单例模式的广泛应用,所以提供了一个更加方便的组件来完成相同的功能:
  1 static unique_ptr<widget> widget::instance;
  2 static std::once_flag widget::create;
  3 widget& widget::get_instance() {
  4     std::call_once(create, [=]{ instance = make_unique<widget>(); });
  5     return instance;
  6 }
  可以看出上面的代码相比较之前的示例代码来说已经相当的简洁了,但是!!!有是但是!!!!在C++memory model中对static local variable,说道:The initialization of such a variable is defined to occur the first time control passes through its declaration; for multiple threads calling the function, this means there’s the potential for a race condition to define first.因此,我们将会得到一份简洁也是效率高的单例模式的C++11实现:
  1 widget& widget::get_instance() {
  2     static widget instance;
  3     return instance;
  4 }
  用Herb Sutter的话来说这份代码实现是“Best of All”的。