简体   繁体   English

Visual Studio 2012中的C ++ 11 Magic Statics解决方法

[英]C++11 Magic Statics Workaround in Visual Studio 2012

I have some objects defined as global, which means their constructor are entered before program start or under DllMain(). 我有一些定义为全局的对象,这意味着它们的构造函数是在程序启动之前或在DllMain()下输入的。 This causes some issues, and that is why I want to move them to local static. 这会导致一些问题,这就是为什么我要将它们移至本地静态。

Our main project are mainly under Visual Studio 2012. According to the these post. 我们的主要项目主要在Visual Studio 2012下。

The Magic Statics is not implemented in Visual Studio 2012 (until VS 2015). Visual Studio 2012中未实现Magic Statics(直到VS 2015)。 So the local static variable initialization is not automatically protected from concurrent access by compiler. 因此,本地静态变量初始化不会自动受到编译器并发访问的保护。

What is a suitable workaround or solution for this case? 在这种情况下,什么是合适的解决方法或解决方案?


Here is what I tried: 这是我尝试过的:

Add a lock to protect. 添加锁以保护。 But if the variable initialized before the function is entered, my lock may be useless... 但是,如果在输入函数之前初始化了变量,我的锁可能就没用了...

// 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;
}

It actually shows as expected. 它实际上显示出预期的效果。 The constructor is called after function is entered. 输入函数后将调用构造函数。

main In
GetCat In
Cat::Cat
GetCat Out
main Out

But I am not sure whether this is a suitable solution. 但是我不确定这是否合适。

Thanks to A. A in comment for the link 18.2.4 Use std::call_once rather than the Double-Checked Locking pattern . 感谢A. A对链接18.2.4的注释。 请使用std :: call_once而不是Double-Checked Locking模式

I referenced the example from the Guildline, and rewrite my singleton getter code as the following. 我从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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM