1. 不安全的实现方法
std::unique_ptr<Interface> instance_(nullptr);static Interface* GetInstance() {if (instance_.get() == nullptr) {instance_.reset(new Interface());}return instance_.get();
}
instance_.reset(new Interface)包含了三步:
1)分配内存;
2)在内存的位置上调用构造函数;
3)将地址赋值给instance_。
CPU在动态调度的时候认为2)和3)的顺序是可以互相颠倒的。因此,如果出现另一个对GetInstance()的并发调用,完全有可能出现因为先调用3),而2)的构造函数操作没完成时,instance_.get() == nullptr判断为false,返回了一个未构造完的instance_导致崩溃。
2. 安全的实现方法
《Effective C++》推荐如下写法,但该写法只对C++11及以后的版本才是安全的。
static Interface* GetInstance() {static Interface instance;return &instance;
}