0

オブジェクトがグローバルに定義されているため、コンストラクタがプログラムの開始前またはDllMain()の下に入力されています。これはいくつかの問題を引き起こします。そのため、それらをローカルの静的に移動したいのです。C++ 11 Magic Stics Visual Studio 2012の回避策

主なプロジェクトは、主にVisual Studio 2012の下にあります。これらの投稿によると、

  • Support For C++11/14/17 Features (Modern C++)
  • マジック静

  • “Magic static” singleton crashing when referenced in static destruction phase of another translation unit"
    • は(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 
      

      しかし、これが適切な解決策であるかどうかはわかりません。

    +1

    'std :: call_once'を試してみることもできます。それも推奨されているように見える[18.2.4 double-Checked Lockingパターンではなくstd :: call_onceを使う](http://www.codingstandard.com/rule/18-2-use-stdcall_once-rather-than-ダブルチェックロックパターン/) –

    答えて

    0

    リンク18.2.4 Use std::call_once rather than the Double-Checked Locking patternのコメントでA. Aのおかげで。

    私はGuildlineの例を参照して、シングルトンゲッターコードを次のように書き直しました。

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