static члены
В определении класса ключевое слово static объявляет члены, не связанные с экземплярами класса.
Вне определения класса оно имеет другое значение: см. длительность хранения.
Синтаксис
Объявление статического члена — это объявление члена, в спецификаторах объявления которого содержится ключевое слово static. Ключевое слово static обычно располагается перед другими спецификаторами (поэтому синтаксис часто неформально описывают как static member-declaration), но может находиться в любом месте последовательности спецификаторов.
Имя любого статического члена данных и любой статической функции-члена должно отличаться от имени содержащего их класса.
Пояснение
Статические члены класса не связаны с объектами этого класса: это независимые переменные со статической или потоковой(начиная с C++11) длительностью хранения или обычные функции.
Ключевое слово static используется только при объявлении статического члена внутри определения класса, но не при определении этого статического члена:
class X { static int n; }; // declaration (uses 'static')
int X::n = 1; // definition (does not use 'static')
Объявление внутри тела класса не является определением и может объявлять член имеющим неполный тип (кроме void), включая тип класса, в котором объявлен этот член:
struct Foo;
struct S
{
static int a[]; // declaration, incomplete type
static Foo x; // declaration, incomplete type
static S s; // declaration, incomplete type (inside its own definition)
};
int S::a[10]; // definition, complete type
struct Foo {};
Foo S::x; // definition, complete type
S S::s; // definition, complete type
| Однако если в объявлении используется спецификатор | (начиная с C++11) |
Для обращения к статическому члену m класса T можно использовать две формы: квалифицированное имя T::m или выражение доступа к члену E.m или E->m, где E — выражение, которое вычисляется в T или T* соответственно. В той же области видимости класса квалификация не требуется:
struct X
{
static void f(); // declaration
static int n; // declaration
};
X g() { return X(); } // some function returning X
void f()
{
X::f(); // X::f is a qualified name of static member function
g().f(); // g().f is member access expression referring to a static member function
}
int X::n = 7; // definition
void X::f() // definition
{
n = 1; // X::n is accessible as just n in this scope
}
К статическим членам применяются правила доступа к членам класса (private, protected, public).
Статические функции-члены
Статические функции-члены не связаны ни с каким объектом. При вызове у них нет указателя this.
Статические функции-члены не могут быть virtual, const, volatile или квалифицированы ссылкой.
Адрес статической функции-члена можно сохранить в обычном указателе на функцию, но не в указателе на функцию-член.
Статические члены данных
Статические члены данных не связаны ни с каким объектом. Они существуют, даже если ни одного объекта класса не было определено. Во всей программе имеется только один экземпляр статического члена данных со статической длительностью хранения, если не используется ключевое слово thread_local; в этом случае для каждого потока существует отдельный такой объект с потоковой длительностью хранения(начиная с C++11).
Статические члены данных не могут быть mutable.
Статические члены данных класса в области видимости пространства имён имеют внешнее связывание, если сам класс имеет внешнее связывание (то есть не является членом безымянного пространства имён). Локальные классы (классы, определённые внутри функций) и безымянные классы, включая классы-члены безымянных классов, не могут иметь статических членов данных.
| Статический член данных может быть объявлен struct X
{
inline static int fully_usable = 1; // No out-of-class definition required,
// ODR-usable
inline static const std::string class_name{"X"}; // Likewise
static const int non_addressable = 1; // C.f. non-inline constants, usable
// for its value, but not ODR-usable
// static const std::string class_name{"X"}; // Non-integral declaration of this
// form is disallowed entirely
};
| (начиная с C++17) |
Константные статические члены
Если статический член данных целочисленного типа или типа перечисления объявлен const (и не volatile), его можно инициализировать с помощью инициализатора, в котором каждое выражение является константным выражением, непосредственно в определении класса:
struct X
{
const static int n = 1;
const static int m{2}; // since C++11
const static int k;
};
const int X::k = 3;
| Если статический член данных типа LiteralType объявлен struct X
{
constexpr static int arr[] = { 1, 2, 3 }; // OK
constexpr static std::complex<double> n = {1,2}; // OK
constexpr static int k; // Error: constexpr static requires an initializer
};
| (начиная с C++11) |
Если константный статический член данных, не являющийся встроенным,(начиная с C++17) или статический член данных constexpr(начиная с C++11)(до C++17) используется по ODR, определение в области видимости пространства имён по-прежнему требуется, но оно не может содержать инициализатор.
| Статический член данных | (начиная с C++17) |
struct X
{
static const int n = 1;
static constexpr int m = 4;
};
const int *p = &X::n, *q = &X::m; // X::n and X::m are ODR-used
const int X::n; // … so a definition is necessary
constexpr int X::m; // … (except for X::m in C++17)
Ключевые слова
Отчёты об ошибках
Следующие отчёты об ошибках, изменяющие поведение, были применены задним числом к ранее опубликованным стандартам C++.
| Отчёт об ошибке | Применяется к | Поведение согласно опубликованному стандарту | Исправленное поведение |
|---|---|---|---|
| CWG 194 | C++98 | имена функций-членов (static) могут совпадать с именем класса | добавлено ограничение на имена (в том числе для нестатических функций-членов) |
Ссылки
- Стандарт C++23 (ISO/IEC 14882:2024):
- 11.4.9 Статические члены [class.static]
- Стандарт C++20 (ISO/IEC 14882:2020):
- 11.4.8 Статические члены [class.static]
- Стандарт C++17 (ISO/IEC 14882:2017):
- 12.2.3 Статические члены [class.static]
- Стандарт C++14 (ISO/IEC 14882:2014):
- 9.4 Статические члены [class.static]
- Стандарт C++11 (ISO/IEC 14882:2011):
- 9.4 Статические члены [class.static]
- Стандарт C++98 (ISO/IEC 14882:1998):
- 9.4 Статические члены [class.static]
См. также
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/language/static