статическая переменная в функции-члене

bool SomeClass::Function( bool thankYou = true )
{

    static bool justAbool = false;
    // Do something with justAbool;
    ...
}

Я искал вокруг, но ничего не могу найти об этом, кроме глобальных переменных или самих функций-членов.

Что делает вышеизложенное, то есть что происходит, сохраняет ли justAbool свое значение после выхода из области видимости? Или он «запоминает» значение, когда снова входит в область видимости?


person Community    schedule 12.02.2011    source источник
comment
Это не совок. Это размах.   -  person Arjun J Rao    schedule 12.02.2011
comment
@Арджун Дж Рао; спасибо за исправление   -  person    schedule 12.02.2011
comment
@Все остальные; может указать только один ответ как принятый. Поэтому я выбираю первое. Спасибо.   -  person    schedule 12.02.2011
comment
@Ксео; В следующий раз напечатаю лучше, упс. Хотя я набрал совок, а не объем. Как я и думал, это так и называется. Поэтому изменил его обратно из-за комментариев после этого. Немного не нравится такая возможность редактирования, это мои слова, а не ваши. Вероятно, это не сделает меня популярным, но эй. В любом случае, спасибо.   -  person    schedule 12.02.2011


Ответы (6)


static при применении к локальной переменной дает этой переменной длительность статического хранения. Это означает, что время жизни justAbool длится до конца программы, а не до конца вызова функции. Его область действия остается прежней, к нему можно получить доступ только по имени в функции после появления объявления.

justAbool будет инициализирован (используя предоставленный инициализатор = false) при первом вызове функции. После этого он сохранит свое предыдущее значение и не будет повторно инициализирован при повторном вызове функции.

Вот некоторые более подробные сведения о продолжительности хранения и времени жизни со ссылками на стандарт.

Если объект имеет длительность статического хранения, это означает, что хранение объекта длится в течение всего времени работы программы (от начала до конца). (3.7.1 [basic.stc.static])

Поскольку bool — это тип без нетривиального конструктора, его время жизни отражает время его хранения, то есть он живет от начала до конца программы. (3.8 [базовая.жизнь])

Все объекты с статической продолжительностью хранения (включая локальные объекты) инициализируются нулями перед любой другой инициализацией. (6.7/4 [stmt.decl]) [Для локальных объектов с инициализатором это довольно академично, потому что нет возможности прочитать их значение до того, как будет достигнуто их объявление.]

Локальные объекты типа POD с статическим сроком хранения, инициализированные с помощью константных выражений, инициализируются перед входом в их блок, в противном случае локальные объекты с статическим сроком хранения инициализируются, когда управление проходит через их объявление. (6,7/4 снова)

Реализация разрешает, но не требует выполнения ранней инициализации в некоторых ситуациях.

person CB Bailey    schedule 12.02.2011
comment
+1 за ссылки из Стандарта. Это прояснило для меня несколько вещей. :-) - person Nawaz; 12.02.2011

Переменная justAbool инициализируется значением false только один раз и инициализируется перед входом в функцию. Значение будет запомнено после выхода из области действия функции. Важно отметить, что это значение также будет совместно использоваться всеми экземплярами SomeClass точно так же, как статическая переменная-член. Переменная justAbool не будет повторно инициализирована, если вы создадите новый экземпляр своего класса, а затем снова вызовете функцию.

person Adam    schedule 04.12.2014
comment
Очень хорошая точка зрения на ценность, разделяемую всеми экземплярами. Это не очевидно. - person Boon; 30.12.2014
comment
@Adam: Да, меня также смутило, будет ли статическая локальная переменная внутри функции-члена использоваться всеми экземплярами класса. Теперь, когда мы знаем, мне интересно, зачем кому-то объявлять и определять статические переменные класса внутри функции-члена, а не внутри файла заголовка/cpp обычным способом. - person nurabha; 09.06.2015
comment
@nurabha Наиболее вероятная причина, по которой нестатическая функция-член имеет локальную статическую переменную, состоит в том, чтобы ограничить видимость этой переменной только этой функцией и предотвратить ее загромождение интерфейса класса. Если данные должны быть общими для всех экземпляров класса, но требуются только этой одной функции, то локальная статическая переменная укажет на это. К сожалению, тот факт, что она является общей для всех экземпляров, неочевиден, поэтому превращение переменной в член статического класса private будет более четко сообщать о намерениях, но позволит другим членам непреднамеренно изменить ее. - person Justin Time - Reinstate Monica; 27.04.2017

Приведенная выше функция делает то же, что и в комментарии // Do something with justAbool;.

А если серьезно, да, переменная static (в данном случае justAbool) внутри функции сохраняет свое значение даже после возврата из функции. Он инициализируется ТОЛЬКО ОДИН РАЗ. И каждый последующий вызов использует его, как если бы это была глобальная переменная. Его время жизни равно окончанию программы.

int f()
{
   static int v = 0;
   return ++v;
}
int main()
{
   cout << f() << endl;
   cout << f() << endl;
   cout << f() << endl;
   cout << f() << endl;
}

Выход:

1
2
3
4

Онлайн-демонстрация: http://www.ideone.com/rvgB5

person Nawaz    schedule 12.02.2011
comment
Что означает время жизни Ifs равно концу программы? Жизнь — это обычно продолжительность, а не момент времени. - person CB Bailey; 12.02.2011

justAbool на самом деле является обычной статической переменной - она ​​существует с самого начала программы и инициализируется только один раз. Особенность в том, что это известно только в этой функции - если вы попытаетесь использовать его вне функции, компилятор не узнает, что это такое.

person Eli Iser    schedule 12.02.2011
comment
@Eli: Это не обязательно верно, оно существует с самого начала программы.. и, скорее всего, неверно. следовательно -1 - person Nawaz; 12.02.2011
comment
@Nawaz: Вот что означает продолжительность статического хранения. То есть один малоинформированный -1. - person CB Bailey; 12.02.2011
comment
@Charles: он инициализируется при первом вызове функции, верно? - person Nawaz; 12.02.2011
comment
@ Чарльз: Да. Это именно то, что я имел в виду. Отредактировал мой предыдущий комментарий! - person Nawaz; 12.02.2011
comment
@Charles - это неверно, нет никакой разницы между статической переменной, находящейся вне функции, и той, которая находится внутри функции. Оба могут быть инициализированы только постоянным значением, и делать это в начале программы (инициализация выполняется до main). Единственная разница заключается в сфере применения. - person Eli Iser; 12.02.2011
comment
@EliIser: Хорошо, строго говоря, типы POD, инициализированные константными выражениями, инициализируются до того, как будет впервые введен их содержащий блок. Хотя это довольно придирчивое различие. - person CB Bailey; 12.02.2011
comment
@Nawaz: Я думаю, что вы путаете инициализацию и длительность хранения. Хранилище для объекта существует на протяжении всей программы. Поскольку это POD-тип, это означает, что объект живет в течение всего времени работы программы. Он инициализируется нулями только до тех пор, пока блок, содержащий его объявление, не будет выполнен первым, когда данный инициализатор действительно используется, но это отдельная проблема. - person CB Bailey; 12.02.2011
comment
@Charles: я думаю, ты прав. Я возвращаю свой отрицательный голос. +1 сейчас. - person Nawaz; 12.02.2011

justAbool сохраняет свое значение после выхода из области видимости. Что еще вы хотели, чтобы этот код делал именно?

person Arjun J Rao    schedule 12.02.2011
comment
он изменен из источника - сужен до базового - и я не знал, что статика тоже может быть в области функций. Поэтому я задавался вопросом, что происходит. msdn тоже не был мне понятен, и я не мог найти ничего другого в сети. Поскольку это, вероятно, общий вопрос, я подумал, что это лучшее место. Это практически то, что я хочу, чтобы этот код делал. - person ; 12.02.2011

статическая локальная переменная функционального уровня, инициализация зависит от типов переменных:

  • POD: инициализирован перед main()
  • не-POD: инициализируется в первый раз, выполняется строка в функции.
person pepero    schedule 22.07.2015