【发布时间】:2018-05-19 23:52:27
【问题描述】:
我有一些定义为全局的对象,这意味着它们的构造函数是在程序启动之前或在 DllMain() 下输入的。这会导致一些问题,这就是我想将它们移动到本地静态的原因。
我们的主要项目主要在 Visual Studio 2012 下。根据这些帖子。
- “Magic static” singleton crashing when referenced in static destruction phase of another translation unit"
- Support For C++11/14/17 Features (Modern C++)
Magic Statics 未在 Visual Studio 2012 中实现(直到 VS 2015)。所以局部静态变量初始化不会被编译器自动保护并发访问。
什么是适合这种情况的解决方法或解决方案?
这是我尝试过的:
添加一个锁来保护。但是如果在进入函数之前初始化的变量,我的锁可能就没用了……
// data object
struct Cat
{
Cat()
{
std::cout << __FUNCTION__ << "\n";
}
};
// lock mutex for singleton getter
static std::mutex getcat_m;
// singleton getter
Cat& GetCat(){
std::cout << __FUNCTION__ << " In\n";
std::lock_guard<std::mutex> lk(getcat_m);
static Cat cat;
std::cout << __FUNCTION__ << " Out\n";
return cat;
}
int main(int argc, char* argv[])
{
std::cout << __FUNCTION__ << " In\n";
Cat& cat = GetCat();
std::cout << __FUNCTION__ << " Out\n";
std::cin.ignore();
return 0;
}
它实际上按预期显示。函数进入后调用构造函数。
main In
GetCat In
Cat::Cat
GetCat Out
main Out
但我不确定这是否是一个合适的解决方案。
【问题讨论】:
-
你也可以试试
std::call_once。貌似也推荐18.2.4 Use std::call_once rather than the Double-Checked Locking pattern
标签: c++ visual-studio c++11 visual-studio-2012 initialization