To answer OPs question why
class Solution {
public:
int m = INT_MIN;
};
is fine but
class Solution {
public:
static int m = INT_MIN;
};
is not:
In short: Prefixing a data-member with static
fundamentally change its meaning.
Without static
, the member variable is part of the class and each instance will provide a separate storage for this member variable.
With static
, the member variable has only scope of the class but there will be only one global storage.
Respectively, the initialization has different meanings too.
For non-static member variables, it provides a default initialization which constructors may use (or override).
Demonstration by Example:
#include <iostream>
enum ArgCase1 { Case1 };
enum ArgCase2 { Case2 };
class Solution {
public:
int m = 123;
Solution() = default; // will use m(123) implicitly
Solution(ArgCase1) { } // will use m(123) implicitly
Solution(ArgCase2): m(456) { } // default of m ignored
};
#define DEBUG(...) std::cout << #__VA_ARGS__ << ";\n"; __VA_ARGS__
int main()
{
DEBUG(Solution sol);
std::cout << "sol.m: " << sol.m << '\n';
DEBUG(Solution sol1(Case1));
std::cout << "sol1.m: " << sol1.m << '\n';
DEBUG(Solution sol2(Case2));
std::cout << "sol2.m: " << sol2.m << '\n';
}
Output:
Solution sol;
sol.m: 123
Solution sol1(Case1);
sol1.m: 123
Solution sol2(Case2);
sol2.m: 456
Live Demo on coliru
For static
member variables, the initialization would be dangerous. Assuming that a class is declared in a header which is included multiple times, this would result in a violation of the One Definition Rule.
In former times, it was usual to declare the static
member variable in the header but to define it in the .cpp
-file (which represents the translation unit).
Expample:
solution.h
:
#ifndef SOLUTION_H
#define SOLUTION_H
class Solution {
public:
static int m;
};
#endif // SOLUTION_H
solution.cc
:
// header of this module:
#include "solution.h"
int Solution::m = 123;
Live Demo on coliru
Since C++17, a new alternative is available – using the keyword inline
.
From cppreference.com – static members – Static data members
A static data member may be declared inline. An inline static data member can be defined in the class definition and may specify an initializer. It does not need an out-of-class definition
Example:
solution.h
:
#ifndef SOLUTION_H
#define SOLUTION_H
class Solution {
public:
inline static int m = 123;
};
#endif // SOLUTION_H
Live Demo on coliru
The advantage is that there is no .cpp
-file needed for this i.e. as it is the class Solution
could be provided as header-only source.
static
anywhere, please show us the code that actually generates that error. – Illonastatic
data member.static
data members are shared between all instances of the class, do you really want every single object of your class to change value ofm
? – Fassoldstatic inline int m=INT_MIN;
? – Winnipegosisstatic
variables in header files isn't a good thing in general. The header might be included more than once and so you get an ODR violation. (ODR - One Definition Rule). Qualifying thisinline
tells the compiler explicitly to sort it out by itself. FYI: Static data members. – Winnipegosisstatic
member variable is very different from a non-static? Astatic
member variable only has the scope of the class but there is only one global storage. I.e. if one instance changes the value it will be changed for all other instances as well (asstatic
member variables actually doesn't belong to any instance). – Winnipegosis