Последнее обновление:2026-10-12
C++ статические члены и время жизни¶
Об авторе¶
Официальный аккаунт в WeChat:

При использовании с разными сущностями ключевое слово static имеет разный смысл. Ключевое слово static можно использовать:
Статические переменные: переменные в функциях, переменные в классах
Статические члены класса: объекты класса и функции в классе
Теперь подробно рассмотрим эти применения static:
Статические переменные
- Статические переменные в функциях
Когда переменная объявлена как static, память под неё выделяется на всё время жизни программы. Даже при многократных вызовах функции память под статическую переменную выделяется только один раз, а значение переменной из предыдущего вызова передаётся в следующий вызов функции. Это очень полезно в C/C++ и в любых других приложениях, где нужно хранить состояние предыдущей функции.
#include <iostream>
#include <string>
using namespace std;
void demo()
{
// static variable
static int count = 0;
cout << count << " ";
// value is updated and
// will be carried to next
// function calls
count++;
}
int main()
{
for (int i=0; i<5; i++)
demo();
return 0;
}
Вывод:
Как видно из приведённой программы, переменная count объявлена как static, поэтому её значение передаётся между вызовами функции. При каждом вызове функции переменная счётчика не инициализируется заново.
- Статические переменные в классах
Поскольку переменные, объявленные как static, инициализируются только один раз — ведь память под них выделяется в отдельном статическом хранилище, — статические переменные в классе разделяются объектами. Для разных объектов не может существовать нескольких копий одной и той же статической переменной. По этой же причине статические переменные нельзя инициализировать с помощью конструктора.
#include<iostream>
using namespace std;
class Apple
{
public:
static int i;
Apple()
{
// Do nothing
};
};
int main()
{
Apple obj1;
Apple obj2;
obj1.i =2;
obj2.i = 3;
// prints value of i
cout << obj1.i<<" "<<obj2.i;
}
Как видно из приведённой программы, мы попытались создать несколько копий статической переменной i для нескольких объектов, но этого не произошло. Поэтому статические переменные в классе должны явно инициализироваться пользователем вне класса с помощью имени класса и оператора разрешения области видимости, как показано ниже:
#include<iostream>
using namespace std;
class Apple
{
public:
static int i;
Apple()
{
// Do nothing
};
};
int Apple::i = 1;
int main()
{
Apple obj;
// prints value of i
cout << obj.i;
}
Вывод:
Статические члены
- Статические объекты класса
Как и переменные, объекты, объявленные как static, существуют до конца времени жизни программы.
Рассмотрим программу, в которой объект является нестатическим.
#include<iostream>
using namespace std;
class Apple
{
int i;
public:
Apple()
{
i = 0;
cout << "Inside Constructor\n";
}
~Apple()
{
cout << "Inside Destructor\n";
}
};
int main()
{
int x = 0;
if (x==0)
{
Apple obj;
}
cout << "End of main\n";
}
Вывод:
В приведённой программе объект объявлен внутри блока if как нестатический, поэтому область видимости переменной ограничена блоком if. При создании объекта вызывается конструктор, а деструктор вызывается, когда управление покидает блок if, поскольку область видимости объекта ограничена блоком if, в котором он объявлен. Если же объявить объект статическим, посмотрим, как изменится вывод.
#include<iostream>
using namespace std;
class Apple
{
int i;
public:
Apple()
{
i = 0;
cout << "Inside Constructor\n";
}
~Apple()
{
cout << "Inside Destructor\n";
}
};
int main()
{
int x = 0;
if (x==0)
{
static Apple obj;
}
cout << "End of main\n";
}
Вывод:
Хорошо видно, как изменился вывод: теперь деструктор вызывается после завершения main. Это происходит потому, что время жизни статического объекта охватывает всю программу.
- Статические функции в классах
Как и статические члены данных или статические переменные класса, статические членские функции не зависят от объектов класса. Нам разрешено вызывать статическую членскую функцию через объект и '.', однако рекомендуется вызывать статический член через имя класса и оператор разрешения области видимости.
Статическим членским функциям разрешён доступ только к статическим членам данных или другим статическим членским функциям; они не могут обращаться к нестатическим членам данных или членским функциям класса.
#include<iostream>
using namespace std;
class Apple
{
public:
// static member function
static void printMsg()
{
cout<<"Welcome to Apple!";
}
};
// main function
int main()
{
// invoking a static member function
Apple::printMsg();
}
Вывод:
Ограничение области доступа У static есть ещё и роль ограничения области доступа (похоже на анонимное пространство имён). Из issue: https://github.com/Light-City/CPlusPlusThings/issues/142
// source1.cpp
extern void sayHello();
const char* msg = "Hello World!\n";
int main()
{
sayHello();
return 0;
}
// source2.cpp
#include <cstdio>
extern char* msg;
void sayHello()
{
printf("%s", msg);
}
// source1.cpp
extern void sayHello();
static const char* msg = "Hello World!\n";
int main()
{
sayHello();
return 0;
}
Похожие темы¶
- C++ чисто виртуальные функции и абстрактные классы | C++那些事
- C++ утверждения assert | C++那些事
- C++ битовые поля | C++那些事
- Реализация полиморфизма C++ на языке C | C++那些事
- C++ константы const и его модификация | C++那些事
- C++ всё семейство const | C++那些事
- C++ оператор разыменования * | C++那些事
- C++ инициализация и присваивание | C++那些事
- C++ возврат нескольких значений | C++那些事
- C++ ключевое слово mutable | C++那些事