Ответ
Ключевое слово static в C++ имеет четыре различных значения в зависимости от контекста:
1. Статические локальные переменные (внутри функций)
void counter() {
static int count = 0; // Инициализируется ОДИН раз при первом вызове
count++;
std::cout << "Вызов №" << count << std::endl;
}
int main() {
counter(); // Вызов №1
counter(); // Вызов №2
counter(); // Вызов №3
// Переменная count сохраняет значение между вызовами
}
2. Статические члены класса
class Logger {
private:
static int instanceCount; // Объявление - общая для всех объектов
public:
Logger() {
instanceCount++; // Увеличиваем общий счётчик
}
static int getInstanceCount() { // Статический метод
return instanceCount; // Работает без объекта
}
static void setLogLevel(int level) { // Ещё один статический метод
// Может обращаться только к статическим полям
}
};
// Определение статического члена (ОБЯЗАТЕЛЬНО в .cpp файле)
int Logger::instanceCount = 0;
int main() {
Logger logger1, logger2, logger3;
std::cout << Logger::getInstanceCount(); // 3 - вызов без объекта
}
3. Статические функции и переменные в области видимости файла
// file1.cpp
static int internalVariable = 42; // Видна ТОЛЬКО в этом файле
static void internalFunction() { // Видна ТОЛЬКО в этом файле
// ...
}
// file2.cpp
extern int internalVariable; // ОШИБКА линковки - не найдена
4. Статические члены в шаблонах
template<typename T>
class TypeTracker {
public:
static int creationCount; // Каждая специализация имеет свою копию
};
// Определение для каждой специализации:
template<typename T>
int TypeTracker<T>::creationCount = 0;
int main() {
TypeTracker<int>::creationCount++;
TypeTracker<double>::creationCount++;
// TypeTracker<int>::creationCount и TypeTracker<double>::creationCount - РАЗНЫЕ переменные
}
Ключевые различия:
- Время жизни: статические переменные живут всю программу (как глобальные)
- Область видимости: ограничена в зависимости от контекста
- Память: статические члены класса не увеличивают размер каждого объекта