Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

why " 'static' may not be used when defining (as opposed to declaring) a static data member"?

Tags:

c++

static

I was looking up ways to initialize static map in C++ and found this code:

struct A{
static map<int,int> create_map()
    {
      map<int,int> m;
      m[1] = 2;
      m[3] = 4;
      m[5] = 6;
      return m;
    }
static const map<int,int> myMap;

};

const map<int,int> A:: myMap =  A::create_map();

However, if I change the last line to

const static map<int,int> A:: myMap =  A::create_map();

Compiler complaints: 'static' may not be used when defining (as opposed to declaring) a static data member" ?

I wonder why? What's the logic or reasoning behind this ?

like image 511
user1861088 Avatar asked Mar 05 '13 22:03

user1861088


People also ask

Why definition of static data member is necessary?

Classes can contain static member data and member functions. When a data member is declared as static , only one copy of the data is maintained for all objects of the class. In the preceding code, the member bytecount is declared in class BufferedOutput , but it must be defined outside the class declaration.

Why must define static data member of class in cpp file?

The reason is that a class might be declared (through #include) in many Translation Units, if it was defined on all of them there would be a repeated symbol. static class members have external linkage, and must comply to the restrictions placed on that model, one definition only.

What is the implication of defining a data member as static?

Once you define a static data member, it exists even though no objects of the static data member's class exist. In the above example, no objects of class X exist even though the static data member X::i has been defined. Static data members of a class in namespace scope have external linkage.

Is a static data member it can only be initialized?

Static data members are initialized when they are defined, outside of any member function, exactly like the initialization of ordinary (non-class) global variables.


3 Answers

static int    a = 0; // grandfathered and still useful, provides static *LINKAGE*
                     // and static STORAGE DURATION
static int X::a = 0; // confusing and illegal, is it static LINKAGE
                     // or static STORAGE DURATION
                     // or static MEMBERSHIP?

static already had a meaning (in C) when used on a variable definition. It would be very surprising for C programmers learning C++ to find that meaning was changed sometimes, but not always.

So the new meaning (static membership) is only active inside the class definition (where C didn't allow the static keyword).

like image 161
Ben Voigt Avatar answered Oct 22 '22 05:10

Ben Voigt


Declaring a class member static means it is shared between all objects of this class.

When you add static to a variable definition outside of a class, it means this variable has file scope and is not visible outside this file.

If it would be allowed to

const static map<int,int> A:: myMap =  A::create_map();

this would mean, you have a static member variable, which is not visible outside of this file. This just doesn't make sense.

like image 36
Olaf Dietsche Avatar answered Oct 22 '22 05:10

Olaf Dietsche


It's no different than

struct A
{
   static int x;
}

int A::x;         //legal
static int A::x;  //illegal

Everything else is just more keywords thrown at this minimal, conceptually identical, example. A static member can only be declared static inside the class definition.

The

const map<int,int> A:: myMap =  A::create_map();

outside the class is just a definition of the static member A::myMap. The extra static makes no sense there.

The reasoning behind this is probably to avoid confusion - a static free variable is kind of a "private" variable (to a translation unit). A member static is the opposite.

like image 35
Luchian Grigore Avatar answered Oct 22 '22 06:10

Luchian Grigore