Чтобы ответить на вопрос ОП, почему
class Solution {
public:
int m = INT_MIN;
};
хорошо, но
class Solution {
public:
static int m = INT_MIN;
};
не является:
Короче: префикс элемента данных с static
принципиально измените его значение.
Без static
переменная-член является частью класса, и каждый экземпляр будет предоставлять отдельное хранилище для этой переменной-члена.
При static
переменная-член имеет только область видимости класса, но будет только одно глобальное хранилище.
Соответственно, инициализация также имеет разные значения.
Для нестатические c переменные-члены, он обеспечивает инициализацию по умолчанию, которую конструкторы могут использовать (или переопределить).
Демонстрация на примере:
#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';
}
Вывод:
Solution sol;
sol.m: 123
Solution sol1(Case1);
sol1.m: 123
Solution sol2(Case2);
sol2.m: 456
Демонстрация в реальном времени на coliru
Для static
переменных-членов инициализация будет опасной. Если предположить, что класс объявлен в заголовке, который включается несколько раз, это приведет к нарушению Единого правила определения .
В прежние времена это обычно объявляли переменную-член static
в заголовке, но определяли ее в .cpp
-файле (который представляет единицу перевода ).
Пример:
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;
Живая демоверсия на coliru
Начиная с C ++ 17, доступна новая альтернатива - с использованием ключевого слова inline
.
From cppreference.com - stati c членов - Стати c членов данных
Статистический элемент данных c может быть объявлен встроенным. Встроенный элемент данных stati c может быть определен в определении класса и может указывать инициализатор. Не требуется внеклассное определение
Пример:
solution.h
:
#ifndef SOLUTION_H
#define SOLUTION_H
class Solution {
public:
inline static int m = 123;
};
#endif // SOLUTION_H
Демонстрация в реальном времени включена coliru
Преимущество состоит в том, что для этого не требуется .cpp
-файл, то есть, поскольку class Solution
может быть предоставлен как источник только для заголовка.