这是MSVC 2013中具有共享PTR的单例的正确实现吗?

Is this right realization of Singleton with shared ptr in MSVC 2013?

本文关键字:单例 实现 PTR 2013 MSVC 共享 这是      更新时间:2023-10-16
struct Foo {
int i_;
Foo(int i) :i_(i) { std::cout << "Foo:" << i_ << "n"; }
~Foo() { std::cout << "~Foo" << i_ << "n"; }
};
class FooSingleton
{
public:
static std::weak_ptr<Foo> GetInstance()
{
auto tmp = std::atomic_load(&instance);
if (tmp == nullptr) {
std::lock_guard<std::mutex> lock(mutex1);
tmp = std::atomic_load(&instance);
if (tmp == nullptr) {
tmp = std::make_shared<Foo>(2);
std::atomic_store(&instance, tmp);
}
}
return tmp;
}
private:
static std::mutex mutex1;
static std::shared_ptr<Foo> instance;
};

正在阅读双重检查锁定 http://preshing.com/20130930/double-checked-locking-is-fixed-in-cpp11/, 但我还需要使用 shared_ptr 来拥有原始指针。

从我知道的文档来看,我不能使用 shared_ptr 作为 std::atomic 的模板(N29.5 中的 §3290 1(

更新:我的实现似乎是正确的(尽管它并不优雅( - 因为它通过了代码审查。谢谢大家!

你根本不需要原始或共享的指针,只需使用引用:

struct Foo {
int i_;
Foo(int i) :i_(i) { std::cout << "Foo:" << i_ << "n"; }
~Foo() { std::cout << "~Foo" << i_ << "n"; }
};

class FooSingleton
{
public:
static FooSingleton& GetInstance()
// ^
{
static FooSingleton theInstance;
return theInstance;
}
Foo foo() {
std::lock_guard<std::mutex> lock(mutex1);
return Foo;
}
void foo(const Foo& value) {
std::lock_guard<std::mutex> lock(mutex1);
foo_ = value;
}
private:
FooSingleton() : foo_(42) {
}
std::mutex mutex1;
Foo foo_;
};

Meyers的Singleton保证是线程安全的。

使用实例互斥锁同步与单一实例执行的任何操作,以防需要线程安全。