【问题标题】:C++11 Magic Statics Workaround in Visual Studio 2012Visual Studio 2012 中的 C++11 魔术静态解决方法
【发布时间】:2018-05-19 23:52:27
【问题描述】:

我有一些定义为全局的对象,这意味着它们的构造函数是在程序启动之前或在 DllMain() 下输入的。这会导致一些问题,这就是我想将它们移动到本地静态的原因。

我们的主要项目主要在 Visual Studio 2012 下。根据这些帖子。

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

但我不确定这是否是一个合适的解决方案。

【问题讨论】:

标签: c++ visual-studio c++11 visual-studio-2012 initialization


【解决方案1】:

感谢A. A 评论链接18.2.4 Use std::call_once rather than the Double-Checked Locking pattern

我引用了 Guildline 中的示例,并将我的单例 getter 代码重写如下。

// Cat.cpp
static std::once_flag once_Cat;
static Cat* gpCat = nullptr;
void init_Cat() { gpCat = new Cat(); }

Cat& GetCat() {
    std::call_once(once_Cat, init_Cat);
    return *gpCat;
}

【讨论】:

    猜你喜欢
    • 2012-01-21
    • 2013-03-03
    • 2011-11-17
    • 2021-03-01
    • 1970-01-01
    • 2013-04-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多