Pavlo Dyban
Pavlo Dyban

Reputation: 1337

Static struct with static members

Today I found myself creating a static array of 2 ints, and because its inline initalization is not allowed in C++ (not C++11), I reverted to using a static variable of type struct.

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

};

I noticed that internal variables are used only once for all instances of struct Margin, so I decided to make them static too.

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

};

What wonders me is the difference between declaring a static struct variable vs. a static struct variable with static members. AFAC static objects are allocated only once in memory, therefore Margin struct wil be allocated only once no matter if my members are static or not.

Do I miss something? Does there exist a difference or is it a mere syntactic sugar?

Upvotes: 13

Views: 60116

Answers (3)

antonijn
antonijn

Reputation: 5760

You seem to be a bit confused about "static structs", because in C++, there are no such things as static structs (as opposed to languages like C#, where static classes are a workaround for the fact that there are no global functions).

What you're doing, is creating an instance of that class, and making the instance (margin) static (and constant). So your struct is not static, you are simply defining a struct, and making a static const instance of it, belonging to MyWidget. The difference between the two given examples now, should be quite obvious.

In the first example, you're creating a static variable called margin, belonging to MyWidget, meaning you can access the horizontal member like so

MyWidget::margin.horizontal

Where margin is the instance you have created.

Whereas if you made the members of the struct static, you would not be able to do that. Instead, you would have to access them like so:

MyWidget::Margin::horizontal

Where Margin is the struct. Note however, that in the second case, there is no need for the static instance margin, since it has no instance fields associated with it.

Upvotes: 17

Arne Mertz
Arne Mertz

Reputation: 24606

There is indeed a difference:

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


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

This creates another instance of Margin, having different members. The static in static const struct Margin {...} margin; applies to the variable margin, not to the class/struct Margin. That means there is only one Margin object shared by all MyWidget objects, but you can very well create other Margin objects having different values. The above code would not compile with horizontal and vertical being static themselves, because then a Margin object would hav no member variables (statics are no real members) and therefore all Margin objects would share the horizontal and vertical values.

Upvotes: 7

sdkljhdf hda
sdkljhdf hda

Reputation: 1407

Yes, there are significant differences. In the both cases you declare MyWidget::margin that is of type MyWidget::Margin and they are static. In first case margin is an object that has two fields, horizontal and vertical. In second case, margin is an object with no fields and you could just drop that object.

In the first case you need to use form margin.vertical (or MyWidget::margin.vertical if accessing from outside MyWidget) to access the fields, in second case, you can do it like this Margin::vertical (or MyWidget::Margin::vertical).

Upvotes: 3

Related Questions