オブジェクトがグローバルに定義されているため、コンストラクタがプログラムの開始前またはDllMain()の下に入力されています。これはいくつかの問題を引き起こします。そのため、それらをローカルの静的に移動したいのです。C++ 11 Magic Stics Visual Studio 2012の回避策
主なプロジェクトは、主にVisual Studio 2012の下にあります。これらの投稿によると、
マジック静
-
は(VS 2015まで)のVisual Studio 2012年に実装されていません。したがって、ローカル静的変数の初期化は、コンパイラーによる並行アクセスから自動的に保護されません。
このケースに適した回避策または解決策は何ですか?
は、ロックが保護するために追加します。ここでは
は、私が試したものです。関数の前に初期化された変数が入力された場合でも、私のロックが...予想通りそれは実際に示し
// 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 double-Checked Lockingパターンではなくstd :: call_onceを使う](http://www.codingstandard.com/rule/18-2-use-stdcall_once-rather-than-ダブルチェックロックパターン/) –