我使用的是 Windows XP / Visual C++ 2008。
我遇到了 C++ 静态初始化顺序问题,我用众所周知的“首次使用时构造”惯用法解决了这个问题:
Foo foo; // Forget this
Foo &foo() // Do this instead
{
// Use ptr, not reference, to avoid destruction order problems
static Foo *ptr = new Foo();
return *ptr;
}
然而,我一直在寻找,似乎 Windows(我的平台)并不保证本地静态的线程安全,尽管它确实为全局静态提供了这种保证。
因此,如果我将对象设置为全局对象,我会获得线程安全性,但会遇到初始化顺序问题。如果我使用“首次使用时构造”,我可以避免初始化顺序问题,但会出现竞争条件。我怎样才能同时解决这两个问题?
在 C++ 2011 中你使用std::call_once()
:
#include <mutex>
void initialize(Foo*& ptr)
{
ptr = new Foo();
}
std::once_flag flag
Foo& foo()
{
static Foo* ptr(0);
std::call_once(flag, initialize, std::ref(ptr));
return *ptr;
}
如果您不能使用 C++2011,您可能想查看系统的底层设施。对于 POSIX 这将是pthread_once()
。我不知道其他平台是如何做到这一点的。
也就是说,我推荐not使用它是因为它本质上是某种形式的全局数据,并且通常没有充分的理由使用它。也有例外,但很少见。实际上极其罕见。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)