Initialize static variables in a C ++ class?

I noticed that some of my functions in the class do not actually access the object, so I made them static . Then the compiler told me that all the variables that they access should also be static - and this is understandable. I have a bunch of string variables like

 string RE_ANY = "([^\\n]*)"; string RE_ANY_RELUCTANT = "([^\\n]*?)"; 

etc. in class. Then I made them all static const , because they never change. However, my program compiles only if I remove them from the class: otherwise MSVC ++ 2010 complains: "Only static constant integral variables can be initialized inside the class."

Well, this is unfortunate. Is there a workaround? I would like to leave them inside the class to which they belong.

+68
c ++ initialization static
Feb 16 '11 at 17:29
source share
9 answers

They cannot be initialized inside the class, but they can be initialized outside the class in the source file:

 // inside the class class Thing { static string RE_ANY; static string RE_ANY_RELUCTANT; }; // in the source file string Thing::RE_ANY = "([^\\n]*)"; string Thing::RE_ANY_RELUCTANT = "([^\\n]*?)"; 

Update

I just noticed the first line of your question - you do not want to make these functions static , you want to make them const . Creating static means that they are no longer associated with the object (therefore, they cannot access non-stationary members), and static data is a shared access to all objects of this type. It may not be the way you want. Making them const simply means that they cannot change any elements, but they can access them.

+116
Feb 16 '11 at 17:32
source share

Mike Seymour gave you the correct answer, but add ...
C ++ only allows you to declare and define in your body class a static const integer , as the compiler reports. So you really can:

 class Foo { static const int someInt = 1; static const short someShort = 2; // etc. }; 

And you cannot do this with any other type, in which case you must define them in your .cpp file.

+28
Feb 16 '11 at 19:03
source share

Static member variables must be declared in the class and then defined outside of it!

There is no workaround, just put your actual definition in the source file.




It smells from your description that you are not using static variables correctly. If they never change, you should use a constant variable, but your description is too general to say anything else.

Static member variables always keep the same value for any instance of your class: if you change the static variable of one object, it will also change for all other objects (and in fact you can also access them without an instance of the class - then is: object).

+15
Feb 16 2018-11-17T00:
source share

Since C ++ 11 can be done inside a class with constexpr .

 class stat { public: // init inside class static constexpr double inlineStaticVar = 22; }; 

Now the variable can be obtained with:

 stat::inlineStaticVar 
+15
Jul 02 '14 at 9:36 on
source share

I find it worth adding that the static variable does not match the constant variable.

using constant variable in class

 struct Foo{ const int a; Foo(int b) : a(b){} } 

and we will declare it as if

 fooA = new Foo(5); fooB = new Foo(10); // fooA.a = 5; // fooB.a = 10; 

For a static variable

 struct Bar{ static int a; Foo(int b){ a = b; } } Bar::a = 0; // set value for a 

which is used like that

 barA = new Bar(5); barB = new Bar(10); // barA.a = 10; // barB.a = 10; // Bar::a = 10; 

You see what is happening here. The constant variable that is initialized with each instance of Foo, since Foo has a value, has a separate value for each instance of Foo and cannot be changed at all by Foo.

Where, as in the case of Bar, this is only one value for Bar :: regardless of the number of instances of Bar. They all share this value, you can also access it, since they are instances of Bar. The static variable also supports the rules for public / private, so you can make it so that only instances of Bar can read the value of Bar :: a;

+9
Feb 16 '11 at 17:44
source share

Just add on top of the other answers. To initialize a complex static member , you can do this as follows:

Declare your static member as usual.

 // myClass.h class myClass { static complexClass s_complex; //... }; 

Make a small function to initialize your class if it is not. This will be called only once when the static member is initialized. (Note that the complexClass copy constructor will be used, so it must be clearly defined).

 //class.cpp #include myClass.h complexClass initFunction() { complexClass c; c.add(...); c.compute(...); c.sort(...); // Etc. return c; } complexClass myClass::s_complex = initFunction(); 
+7
Jul 01 '15 at 9:17
source share

If your goal is to initialize a static variable in your header file (instead of the * .cpp file, which you might need if you stick with the header-only idiom), then you can work around the initialization problem using a template. Template static variables can be initialized in the header without causing multiple character definitions.

See an example here:

Static member initialization in a class template

+2
Feb 11 '15 at 18:03
source share

If necessary, move all your constants to a .cpp file without declaration in the .h file. Use an anonymous namespace to make them invisible outside of the cpp module.

 // MyClass.cpp #include "MyClass.h" // anonymous namespace namespace { string RE_ANY = "([^\\n]*)"; string RE_ANY_RELUCTANT = "([^\\n]*?)"; } // member function (static or not) bool MyClass::foo() { // logic that uses constants return RE_ANY_RELUCTANT.size() > 0; } 
+1
Jun 11 '15 at 12:02
source share

Some answers seem a little misleading .

You do not need...

  • During initialization, assign a value to some static object, since value assignment is optional .
  • Create another .cpp file for initialization, as this can be done in the same header file.

In addition, you can even initialize a static object in the same scope as a regular variable using the inline .




Initialize without values ​​in one file

 #include <string> class A { static std::string str; static int x; }; std::string A::str; int A::x; 

Initialization with values ​​in the same file

 #include <string> class A { static std::string str; static int x; }; std::string A::str = "SO!"; int A::x = 900; 

Initialize in the same scope of the class using the inline

 #include <string> class A { static inline std::string str = "SO!"; static inline int x = 900; }; 
+1
May 11 '18 at 18:30
source share



All Articles