Ключевое слово static
в C/C++ меняет время жизни и область видимости переменных в зависимости от контекста использования. Рассмотрим его поведение для разных типов переменных.
// file.cpp
static int globalVar = 42; // static глобальная переменная
Эффекты:
Пример проблемы без static:
// file1.cpp
int sharedVar = 10; // Будет конфликт при линковке
// file2.cpp
int sharedVar = 20; // Ошибка: multiple definition
Решение с static:
// file1.cpp
static int localToFile1 = 10; // Видна только в file1.cpp
// file2.cpp
static int localToFile2 = 20; // Видна только в file2.cpp
void func() {
static int counter = 0; // static локальная переменная
counter++;
}
Эффекты:
Пример использования:
void callCounter() {
static int calls = 0;
std::cout << "Функция вызвана " << ++calls << " раз\n";
}
class MyClass {
public:
static int classVar; // Статическая переменная класса
};
Эффекты:
int MyClass::classVar = 0; // Определение static-переменной
Характеристика | Глобальный static | Локальный static | Член класса static |
---|---|---|---|
Время жизни | Вся программа | Вся программа | Вся программа |
Область видимости | Файл | Функция | Класс |
Память | Статическая | Статическая | Статическая |
Инициализация | Один раз | При первом вызове | Один раз |
Паттерн Singleton (использование static):
class Singleton {
public:
static Singleton& getInstance() {
static Singleton instance; // Гарантирует единственность
return instance;
}
private:
Singleton() {} // Приватный конструктор
};
Счетчик экземпляров класса:
class Widget {
public:
Widget() { ++count; }
```Widget() { --count; }
static int getCount() { return count; }
private:
static int count; // Общий для всех экземпляров
};
int Widget::count = 0; // Определение
Неопределение static-члена класса
Забывают вынести определение за пределы класса
Предположение о потокобезопасности
static локальные переменные не всегда thread-safe
Использование static для временных данных
Неоправданное увеличение времени жизни переменных
Резюмируем: ключевое слово static
предоставляет механизмы управления временем жизни и областью видимости переменных. Для глобальных переменных оно ограничивает видимость файлом, для локальных - сохраняет значение между вызовами, а для членов класса создает общие для всех экземпляров данные.