11

今日、私は 2 つの int の静的配列を作成していることに気付きました。そのインライン初期化は C++ (C++11 ではない) では許可されていないため、構造体型の静的変数の使用に戻りました。

class MyWidget {
  ...
  static const struct Margin {
    const int horizontal = 1;
    const int vertical = 1;
  } margin;

};

内部変数は struct Margin のすべてのインスタンスに対して 1 回しか使用されないことに気付きました。そのため、内部変数も静的にすることにしました。

class MyWidget {
  ...
  static const struct Margin {
    static const int horizontal = 1;
    static const int vertical = 1;
  } margin;

};

私が不思議に思うのは、静的構造体変数と静的メンバーを持つ静的構造体変数の宣言の違いです。AFAC 静的オブジェクトはメモリ内で 1 回だけ割り当てられるため、メンバーが静的であるかどうかに関係なく、Margin 構造体は 1 回だけ割り当てられます。

私は何かが恋しいですか?違いはありますか、それとも単なる構文糖衣ですか?

4

3 に答える 3

12

「静的構造体」について少し混乱しているようです。C++ には静的構造体などがないためです (静的クラスがグローバル関数がないという事実の回避策である C# などの言語とは対照的に)。

あなたがしていることは、そのクラスのインスタンスを作成し、インスタンス( margin) を静的 (および定数) にすることです。したがって、構造体は静的ではありません。単に構造体を定義し、そのstatic constインスタンスを作成して、に属していMyWidgetます。与えられた 2 つの例の違いは明らかです。

最初の例では、 に属する margin という静的変数を作成しています。つまり、次のようにメンバーにMyWidgetアクセスできます。horizontal

MyWidget::margin.horizontal

margin作成したインスタンスはどこにありますか。

一方、構造体のメンバーを静的にすると、それができなくなります。代わりに、次のようにアクセスする必要があります。

MyWidget::Margin::horizontal

はどこMarginですかstruct。ただし、2 番目のケースではmargin、インスタンス フィールドが関連付けられていないため、静的インスタンスは必要ないことに注意してください。

于 2013-02-20T10:15:59.530 に答える
7

確かに違いがあります:

class MyWidget {
  ...
  static const struct Margin {
    const int horizontal = 1;
    const int vertical = 1;
  } margin;


  void foo() {
    Margin anotherMargin = { 3, 4 };
  }
};

これにより、異なるメンバーを持つMarginの別のインスタンスが作成されます。staticinは、クラス/構造体ではなくstatic const struct Margin {...} margin;、変数に適用されます。つまり、すべてのMyWidgetオブジェクトで共有されるMarginオブジェクトは1つだけですが、値が異なる他のMarginオブジェクトを非常にうまく作成できます。上記のコードは、それ自体が静的であるとコンパイルされません。これは、Marginオブジェクトがメンバー変数を持たず(静的は実際のメンバーではない)、したがってすべてのMarginオブジェクトがとの値を共有するためです。marginMarginhorizontalverticalhorizontalvertical

于 2013-02-20T10:12:35.940 に答える
3

はい、大きな違いがあります。どちらの場合も、MyWidget::marginそれはタイプMyWidget::Marginであり、静的であると宣言します。最初のケースは、2つのフィールドをmargin持つオブジェクトです。2番目のケースでは、はフィールドのないオブジェクトであり、そのオブジェクトをドロップするだけで済みます。horizontalverticalmargin

最初のケースでは、フォームを使用してmargin.vertical(またはMyWidget::margin.vertical外部からアクセスする場合)フィールドにアクセスする必要があります。2番目のケースでは、このように(または)MyWidget行うことができます。Margin::verticalMyWidget::Margin::vertical

于 2013-02-20T10:12:10.293 に答える