Initialize static variables in C++ class?
They can't be initialised inside the class, but they can be initialised outside the class, in a 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've just noticed the first line of your question - you don't want to make those functions static
, you want to make them const
. Making them static
means that they are no longer associated with an object (so they can't access any non-static members), and making the data static means it will be shared with all objects of this type. This may well not be what you want. Making them const
simply means that they can't modify any members, but can still access them.
The initialization of static variables in C
Yes, all members are initialized for objects with static storage. See 6.7.8/10 in the C99 Standard (PDF document)
If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate. If an object that has static storage duration is not initialized explicitly, then:
— if it has pointer type, it is initialized to a null pointer;
— if it has arithmetic type, it is initialized to (positive or unsigned) zero;
— if it is an aggregate, every member is initialized (recursively) according to these rules;
— if it is a union, the first named member is initialized (recursively) according to these
rules.
To initialize everything in an object, whether it's static
or not, to 0, I like to use the universal zero initializer
sometype identifier0 = {0};
someothertype identifier1[SOMESIZE] = {0};
anytype identifier2[SIZE1][SIZE2][SIZE3] = {0};
There is no partial initialization in C. An object either is fully initialized (to 0
of the right kind in the absence of a different value) or not initialized at all.
If you want partial initialization, you can't initialize to begin with.
int a[2]; // uninitialized
int b[2] = {42}; // b[0] == 42; b[1] == 0;
a[0] = -1; // reading a[1] invokes UB
How to initialize private static members in C++?
The class declaration should be in the header file (Or in the source file if not shared).
File: foo.h
class foo
{
private:
static int i;
};
But the initialization should be in source file.
File: foo.cpp
int foo::i = 0;
If the initialization is in the header file then each file that includes the header file will have a definition of the static member. Thus during the link phase you will get linker errors as the code to initialize the variable will be defined in multiple source files.
The initialisation of the static int i
must be done outside of any function.
Note: Matt Curtis: points out that C++ allows the simplification of the above if the static member variable is of const integer type (bool
, char
, char8_t
[since C++20], char16_t
, char32_t
, wchar_t
, short
, int
, long
, long long
, or any implementation-defined extended integer types, including any signed, unsigned, and cv-qualified variants.). You can then declare and initialize the member variable directly inside the class declaration in the header file:
class foo
{
private:
static int const i = 42;
};
c# initialize static variable from different classes
This is because the static constructor is called automatically before the first instance is created or any static members are referenced..
This means that when an instance of otherClass
invokes IDs.someID = sym;
the first operation that gets executed is the static constructor, i.e. the code inside static IDs()
.
At this point the static variable has not yet been initialized, and you are basically executing log.info(null);
.
After the static constructor completes, the variable is initialized, so you should be able to see its value inside otherMethod
, after the first reference of IDs
.
Given the OP's requirement:
I want to use the value passed in someID
in a switch statement
The solution could be to simply execute a static method whenever a new value is set, with the help of explicit getters and setters:
public static class IDs
{
private static string _someID; // backing field
public static string SomeID
{
get { return _someID; }
set
{
_someID = value;
DoSomethingWithSomeID();
}
}
private static DoSomethingWithSomeID()
{
// Use SomeID here.
switch (IDs.SomeID)
{
...
}
}
}
public class OtherClass
{
public void OtherMethod(string sym)
{
// This will set a new value to the property
// and invoke DoSomethingWithSomeID.
IDs.SomeID = sym;
}
}
DoSomethingWithSomeID
will be invoked every time someone sets a new value to SomeID
.
How to declare and initialize a static member in a class?
One can definitely have class static members which are not CV-qualified (non const and not volatile). It is just that one should not initialize them (give them value) when one declare them inside the class, based on current ISO C++ regulations. In Comparison, it is OK to do so for non static data members(regardless of CV-qualification) Since C++11.
Because static data members do not belong to any object, with the right access they can be assigned (and if they are not constant, they can be manipulated) outside of the class(keeping in mind the right scope operator). Also regardless of public/private declaration and CV-qualification, static data members can be initialized outside their class.
So one way for initializing static data members, is to do so in the same block-scope/namespace where their classes(outer class in case of sub-classes) are situated, but not inside any class scope.
For example:
class Graph {
public:
class Node {
public:
static int maxNumberOfNeighbors;
.
.
.
};
.
.
.
};
int Graph::Node::maxNumberOfNeighbors = 4;
//also int Graph::Node::maxNumberOfNeighbors(4);
Good luck!
Why should I initialize static class variables in C++?
At class scope,
int MyClass::classVar = 0; // Why I have to init it here?
is a definition and
static int classVar;
is a declaration, ie. a promise the variable will be defined somewhere: you must define exactly once the variables you declare.
The rationale is that the class declaration will likely be included in multiple source files. Would a part of it be a definition, it would take place multiply: this is erroneous (exceptions are inline [member] functions).
Note that according to value initialization rules, you can get along with
int MyClass::classVar; // Zero-initialized !
as a definition.
Variables declared at namespace scope are definitions too (unless they are extern
qualified):
int var;
is a declaration, and a definition: if you put this into a header and include it in multiple translation units, you have an error ("multiply defined symbol", or something along those lines).
[Note that in C++ (and not in C), if the var
above is const
, it becomes automatically static
and there is no violation of the One Definition Rule should it be put into a multiply included header. This goes slightly off topic, but feel free to ask details]
C static variables and initialization
There is a nice answer here:
Just a short excerpt:
First of all in ISO C (ANSI C), all static and global variables must be initialized before the program starts. If the programmer didn't do this explicitly, then the compiler must set them to zero. If the compiler doesn't do this, it doesn't follow ISO C. Exactly how the variables are initialized is however unspecified by the standard.
Related Topics
How to Get Current Time and Date in C++
Using Custom Std::Set Comparator
Array[N] VS Array[10] - Initializing Array With Variable VS Numeric Literal
Initialization Order of Class Data Members
Two Different Values At the Same Memory Address
Why Does the Use of 'New' Cause Memory Leaks
Measuring Execution Time of a Function in C++
How to Implement Big Int in C++
Difference Between Static and Dynamic Arrays in C++
How to Convert Vector to Array
What Happens If You Call Erase() on a Map Element While Iterating from Begin to End
Evaluating Arithmetic Expressions from String in C++
What Is the Performance Overhead of Std::Function
Why Should One Not Derive from C++ Std String Class
When Does a Constexpr Function Get Evaluated At Compile Time