11

今天我发现自己创建了一个由 2 个整数组成的静态数组,并且因为在 C++(不是 C++11)中不允许它的内联初始化,所以我恢复使用 struct 类型的静态变量。

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

};

我注意到内部变量只对 struct Margin 的所有实例使用一次,所以我决定也将它们设为静态。

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

};

让我感到奇怪的是声明静态结构变量与使用静态成员的静态结构变量之间的区别。AFAC 静态对象在内存中只分配一次,因此无论我的成员是否是静态的,Margin 结构都只会分配一次。

我错过了什么吗?是否存在差异,还是仅仅是语法糖?

4

3 回答 3

12

您似乎对“静态结构”有点困惑,因为在 C++ 中,没有静态结构之类的东西(与 C# 等语言相反,静态类是没有全局函数的解决方法)。

您正在做的是创建该类的实例,并使实例( margin) 静态(和常量)。所以你的结构不是静态的,你只是定义一个结构,并创建static const它的一个实例,属于MyWidget. 现在给出的两个示例之间的区别应该是非常明显的。

在第一个示例中,您正在创建一个名为 margin 的静态变量,属于MyWidget,这意味着您可以horizontal像这样访问该成员

MyWidget::margin.horizontal

margin您创建的实例在哪里。

而如果您将结构的成员设为静态,您将无法做到这一点。相反,您必须像这样访问它们:

MyWidget::Margin::horizontal

Margin在哪里struct。但是请注意,在第二种情况下,不需要静态实例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 实例,具有不同的成员。staticinstatic const struct Margin {...} margin;适用于 variable ,而不适用于marginclass/struct Margin。这意味着所有 MyWidget 对象只共享一个 Margin 对象,但是您可以很好地创建具有不同值的其他 Margin 对象。上面的代码本身不会编译horizontal并且vertical是静态的,因为这样 Margin 对象将没有成员变量(静态不是真正的成员),因此所有 Margin 对象都将共享horizontalvertical值。

于 2013-02-20T10:12:35.940 回答
3

是的,存在显着差异。在这两种情况下,您都声明MyWidget::margin它是类型MyWidget::Margin并且它们是静态的。在第一种情况下margin,是一个具有两个字段的对象,horizontal并且vertical. 在第二种情况下,margin是一个没有字段的对象,您可以删除该对象。

在第一种情况下,您需要使用表单margin.vertical(或者MyWidget::margin.vertical如果从外部访问MyWidget)来访问字段,在第二种情况下,您可以这样做Margin::vertical(或MyWidget::Margin::vertical)。

于 2013-02-20T10:12:10.293 回答