2012-12-05 3 views
1

Мне было интересно, как работает статичность. Вот пример:Статические целые числа

void count() 
{ 
    static int x = 1; 
    cout << "Static: " << x << endl; 
    x++; 

    return; 
} 

int main() 
{ 
    //Static variable test 
    cout << endl; 
    count(); 
    count(); 
} 

Эта программа дает выход «1 и 2». Но мне было интересно, когда функция «count» вызывается во второй раз, почему не выполняется строка «static int x = 1»?

ответ

6

Это языковое правило; инициализация переменной static выполняется только один раз.

Обратите внимание, что это отличается от

static int x; 
x = 1; 

, который бы сбросить x 1 в каждом вызове.

1

Вот что говорят правила. Вы можете думать о линии static как выполненной только при первом вызове функции.

1

Это. В противном случае вы не сможете прочитать значение x. Однако он не устанавливает значение x, если оно уже создано.

2

Статические локальные вары похожи на глобалы, за исключением того, что компилятор позволяет только одной функции получить доступ к ней. Все статически распределенные объекты (встроенные или определяемые пользователем типы), включая статические переменные-члены structs/classes, инициализируются один раз системой до того, как он вызовет вашу функцию main(). Вы можете использовать эту характеристику в своих интересах (или получить какое-то любопытное поведение, если вы не знаете, что происходит) путем создания экземпляров класса (или статических файлов) класса и конструктора классов сделать что-то интересное. Этот код будет запущен до запуска main().

НО. Вы должны быть осторожны, делая это. Нет стандартного способа принудительного упорядочения этих инициализированных объектов, поэтому, если кто-то зависит от того, что уже было уже инициализировано, то, что «отлично работает» в один прекрасный день, может начать «не работать нормально», когда вы изменяете параметры компилятора или компилятора или добавляете/удаляете исходные файлы и т. д.

+0

Какие интересные вещи вы можете сделать в точности? – Josh

+1

Мы используем эту характеристику для добавления модульных тестов в глобальный массив модульных тестов для запуска. Мы используем макрос TESTCASE (test_name), который создает глобальную переменную с именем test_name ## _ XXXX (я не помню, что такое XXXX, но ## добавляет _XXXX в текст «тестовое имя» и делает его одним идентификатором) , Глобальная переменная имеет тип, конструктор которого просто добавляет указатель функции к следующей функции в глобальный массив для последующего выполнения. Затем макрос заканчивается созданием сигнатуры для самой тестовой функции, после чего вы добавляете фигурные скобки и начинаете код тестовой функции. – phonetagger

+0

... Таким образом, вам не нужно создавать файл заголовка, объявляющий о существовании вашей функции тестирования устройства, а затем перейдите к основному файлу «файл сценария теста» и добавьте новую функцию в постоянно растущий список тестов для запуска, который будет распространять его на три файла. Таким образом, весь модульный тест изолирован только несколькими строками одного файла, и его также легко отключить прямо в источнике, не переходя в отдельный файл, чтобы прокомментировать его. – phonetagger

Смежные вопросы