In C++, static
members may not be initialized in the class body with these exceptions:
static
members of const
integral type can bestatic
members of constexpr
literal type must beCan you explain why these exceptions?
Also, this holds:
Even if a
const static
data member is initialized in the class body, that member ordinarily should be defined outside the class definition.
This I never understood at all. What's the point of this extra definition?
Just trying to get some intuitions here.
Static Data Member Initialization in C++ We can put static members (Functions or Variables) in C++ classes. For the static variables, we have to initialize them after defining the class. To initialize we have to use the class name then scope resolution operator, then the variable name. Now we can assign some value.
4. Which is the correct syntax for declaring static data member? Explanation: The syntax must firstly be mentioned with the keyword static. Then the data type of the member followed by the member name should be given.
What is correct about the static data member of a class? A static member function can access only static data members of a class. A static data member is shared among all the object of the class.
8.1: Static data. Any data member of a class can be declared static ; be it in the public or private section of the class interface. Such a data member is created and initialized only once, in contrast to non-static data members which are created again and again for each object of the class.
Why can there be an initializer in the class definition?
Concerning the two exceptions for const
and constexpr
static data members:
[class.static.data]/3
[ Note: In both these cases, the member may appear in constant expressions. — end note ]
I.e. with an initializer, you may use them in constant expressions, e.g.
struct s
{
static std::size_t const len = 10;
int arr[len];
};
std::size_t const s::len;
If len
wasn't initialized in the class definition, the compiler couldn't easily know its value in the next line to define the length of arr
.
One could argue about allowing initializers for of non-const
, non-constexpr
static data members in the class definition, but this could interfere with the initialization order:
[basic.start.init]/2
Definitions of explicitly specialized class template static data members have ordered initialization. Other class template static data members (i.e., implicitly or explicitly instantiated specializations) have unordered initialization. Other non-local variables with static storage duration have ordered initialization.
That is, the order of the definitions including initializers is important. The order of (dynamic) initialization of non-local objects is only defined within a translation unit, this is another reason why there has to be a definition including initializer for non-const
, non-constexpr
static data members.
What's the point of this extra definition?
This has already been answered in the comments IMO. You might want to add the ODR, that is, as a name with external linkage, the static data member must (only) be defined in one translation unit (if it's ODR-used). It's up to the programmer to choose this translation unit.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With