Статические переменные в функциях-членах
Может кто-нибудь объяснить, как статические переменные в функциях-членах работают в C++.
Учитывая следующий класс:
class A {
void foo() {
static int i;
i++;
}
}
Если я объявляю несколько экземпляров A
звонит foo()
на один раз увеличить статическую переменную i
во всех случаях? Или только тот, который был вызван?
Я предполагал, что каждый экземпляр будет иметь свою собственную копию i
, но пошаговое выполнение кода, которое я имею, указывает на обратное.
3 ответа
Поскольку class A
это не шаблонный класс и A::foo()
это не шаблонная функция Там будет только одна копия static int i
внутри программы.
Любой экземпляр A
объект будет влиять на то же самое i
и продолжительность жизни i
останется на протяжении всей программы. Чтобы добавить пример:
A o1, o2, o3;
o1.foo(); // i = 1
o2.foo(); // i = 2
o3.foo(); // i = 3
o1.foo(); // i = 4
Ключевое слово static
к сожалению, в С ++ есть несколько разных значений
При использовании для элементов данных это означает, что данные размещаются в классе, а не в экземплярах.
При использовании для данных внутри функции это означает, что данные распределяются статически, инициализируются при первом вводе блока и сохраняются до завершения программы. Также переменная видна только внутри функции. Эта особенность локальной статики часто используется для реализации ленивых конструкций синглетонов.
При использовании на уровне модуля компиляции (модуля) это означает, что переменная похожа на глобальную (то есть размещается и инициализируется перед
main
запускается и уничтожается послеmain
выход), но переменная не будет доступна или не видна в других единицах компиляции.
Я добавил акцент на части, которая наиболее важна для каждого использования. Использование (3) несколько не рекомендуется в пользу безымянных пространств имен, которые также допускают неэкспортированные объявления классов.
В вашем коде static
Ключевое слово используется со значением 2 и не имеет ничего общего с классами или экземплярами... это переменная функции, и будет только одна ее копия.
Как правильно сказал iammilind, однако, могло бы быть несколько экземпляров этой переменной, если функция была функцией шаблона (потому что в этом случае сама функция может присутствовать во многих различных копиях в программе). Даже в этом случае, конечно, классы и экземпляры не имеют значения... см. Следующий пример:
#include <stdio.h>
template<int num>
void bar()
{
static int baz;
printf("bar<%i>::baz = %i\n", num, baz++);
}
int main()
{
bar<1>(); // Output will be 0
bar<2>(); // Output will be 0
bar<3>(); // Output will be 0
bar<1>(); // Output will be 1
bar<2>(); // Output will be 1
bar<3>(); // Output will be 1
bar<1>(); // Output will be 2
bar<2>(); // Output will be 2
bar<3>(); // Output will be 2
return 0;
}
Статические переменные внутри функций
Статическая переменная создается внутри функции и сохраняется в статической памяти программы, а не в стеке.
Инициализация статической переменной будет произведена при первом вызове функции.
Статическая переменная сохранит значение при нескольких вызовах функций
Время жизни статической переменной - Program
Примеры
#include <iostream>
using namespace std;
class CVariableTesting
{
public:
void FuncWithStaticVariable();
void FuncWithAutoVariable();
};
void CVariableTesting::FuncWithStaticVariable()
{
static int staticVar = 0; //staticVar is initialised by 0 the first time
cout<<"Variable Value : "<<staticVar<<endl;
staticVar++;
}
void CVariableTesting::FuncWithAutoVariable()
{
int autoVar = 0;
cout<<"Variable Value : "<<autoVar<<endl;
autoVar++;
}
int main()
{
CVariableTesting objCVariableTesting;
cout<<"Static Variable";
objCVariableTesting.FuncWithStaticVariable();
objCVariableTesting.FuncWithStaticVariable();
objCVariableTesting.FuncWithStaticVariable();
objCVariableTesting.FuncWithStaticVariable();
objCVariableTesting.FuncWithStaticVariable();
cout<<endl;
cout<<"Auto Variable";
objCVariableTesting.FuncWithAutoVariable();
objCVariableTesting.FuncWithAutoVariable();
objCVariableTesting.FuncWithAutoVariable();
objCVariableTesting.FuncWithAutoVariable();
objCVariableTesting.FuncWithAutoVariable();
return 0;
}
Выход:
Статическая переменная
Значение переменной: 0
Значение переменной: 1
Значение переменной: 2
Значение переменной: 3
Значение переменной: 4
Автоматическая переменная
Значение переменной: 0
Значение переменной: 0
Значение переменной: 0
Значение переменной: 0
Значение переменной: 0
Упрощенный ответ:
Статические переменные, независимо от того, являются ли они членами (не шаблонными) class
или (не шаблонная) функция, технически похожая на глобальную метку, область действия которой ограничена class
или функция.