0

私は 2 つのクラス A と B を持っているので、A はそのメンバーとして静的な B インスタンスを持ちます。B には関数 Show() があり、ここに私のクラス A があります。

class A
{
  A()
  {
    _b.Show();
  }
private:

  static B _b; 
};

そしてその後のコードは

A a;
B A::_b;

int main()
{
}

ここで、a と _b を定義したシーケンスにより、B が構築される前に B::Show() が呼び出されます。しかし、これは正確にはどのように機能するのでしょうか。つまり、まだ構築されていないオブジェクトを呼び出すにはどうすればよいのでしょうか?

4

3 に答える 3

4

aは の前に初期化されるため、未定義の動作です (この場合、初期化されていないオブジェクトにアクセスしているため) A::_b

静的初期化順序 fiasco を調べます。これは 99% の確率で発生し、簡単には診断できないため、エラーは発生しません。

于 2012-10-04T10:05:32.680 に答える
2

これは、静的な初期化順序の問題です。一般的なケースでは解決が困難ですが、一部のケースを修正する 1 つの方法は、次のように依存関係を関数内に配置することです。

class A
{
public:
    A()
    {
        getB().Show();
    }
private:
    static B& getB()
    {
        static B b;
        return b;
    }
};

関数内の statics は、最初に呼び出されたときに初期化されることが保証されています。さらに、C++11 では、スレッドセーフであることが保証されています。

参考文献:

http://www.parashift.com/c++-faq/static-init-order-on-first-use.html

C++ の静的初期化順序の問題を見つける

于 2012-10-04T10:11:42.833 に答える
0

まだ構築されていないオブジェクトを呼び出すにはどうすればよいですか?

簡単な答えは、まさにそのコードのやり方です。<g>。同じ変換単位のファイルスコープで定義されたオブジェクトは、定義が発生する順序で作成されるため、あるオブジェクトのコンストラクターが別のオブジェクトに依存している場合は、2番目のオブジェクトのコンストラクターがすでに作成されていることを確認する必要があります。最初のオブジェクトが実行されます。

C++はここでは何の助けも提供しません。あなたはそれを自分で追跡しなければなりません。

于 2012-10-04T11:21:43.810 に答える