C++
Как обнулить static переменную в C++: локальная static, поле класса и reset-функция
static переменная в C++ сохраняет значение дольше обычной локальной переменной. Как ее обнулить, зависит от того, где она объявлена и есть ли у вас к ней доступ
Короткий ответ: если переменная доступна, просто присвойте ей 0 или другое начальное значение. Если это локальная static внутри функции, снаружи напрямую ее обнулить нельзя — нужно предусмотреть функцию сброса или изменить структуру кода
Обычная static переменная в области файла
Пример:
#include <iostream>
static int counter = 0;
void increment() {
++counter;
}
void resetCounter() {
counter = 0;
}
int main() {
increment();
increment();
std::cout << counter << "\n";
resetCounter();
std::cout << counter << "\n";
return 0;
}
Здесь counter доступен функциям в этом же файле, поэтому его можно обнулить обычным присваиванием:
counter = 0;
Локальная static внутри функции
Более частый случай:
int nextId() {
static int id = 0;
return ++id;
}
Переменная id создается один раз и сохраняет значение между вызовами. Но она видна только внутри функции nextId. Снаружи написать id = 0 нельзя
Один из вариантов — добавить параметр сброса:
int nextId(bool reset = false) {
static int id = 0;
if (reset) {
id = 0;
return id;
}
return ++id;
}
Использование:
std::cout << nextId() << "\n"; // 1
std::cout << nextId() << "\n"; // 2
nextId(true); // сброс
std::cout << nextId() << "\n"; // 1
Такой подход работает, но у него есть минус: функция начинает делать две разные вещи. В реальном коде часто лучше вынести состояние в класс
Вариант через класс
Более управляемый способ:
#include <iostream>
class IdGenerator {
public:
int next() {
return ++id;
}
void reset() {
id = 0;
}
private:
int id = 0;
};
int main() {
IdGenerator generator;
std::cout << generator.next() << "\n";
std::cout << generator.next() << "\n";
generator.reset();
std::cout << generator.next() << "\n";
return 0;
}
Здесь уже не нужен static: состояние принадлежит объекту, а сброс сделан явным методом reset
Static поле класса
Если переменная объявлена как static-поле класса, ее можно сбросить через имя класса, если доступ разрешен:
#include <iostream>
class Counter {
public:
static int value;
static void reset() {
value = 0;
}
};
int Counter::value = 0;
int main() {
Counter::value = 5;
Counter::reset();
std::cout << Counter::value << "\n";
return 0;
}
Если поле private, лучше сделать публичный метод reset, а не открывать переменную напрямую
Частые ошибки
Пытаться обратиться к локальной static снаружи
Локальная static сохраняет значение, но область видимости у нее локальная. Снаружи функции переменная недоступна
Использовать static там, где нужен объект
Если состояние нужно сбрасывать, тестировать и создавать заново, часто удобнее класс или структура, а не скрытая локальная static
Путать обнуление и повторную инициализацию
Локальная static инициализируется один раз. Присваивание 0 сбрасывает значение, но не запускает заново процесс инициализации как при первом входе в функцию
Короткий вывод
Чтобы обнулить static переменную, присвойте ей 0, если у вас есть доступ. Для локальной static сделайте явную функцию сброса или вынесите состояние в объект. Если переменная является static-полем класса, удобнее сбрасывать ее через статический метод reset
Связанные материалы:
Что почитать дальше по C++
Если нужен общий маршрут по теме, откройте рубрику C++. Для соседних задач пригодятся эти разборы:
- Как очистить переменную string в C++: clear, присваивание пустой строки и erase
- Конвертирование в C++: строки, числа и static_cast
- C++ с нуля: первый файл, переменные и вывод
- Enter в C++: перенос строки, std::endl и ввод через cin