Spec-Zone.ru › C++

static члены

Внутри определения класса ключевое слово static объявляет члены, которые не привязаны к экземплярам класса.

Вне определения класса оно имеет другое значение: см. срок хранения.

Синтаксис

Объявление статического члена — это объявление члена, в спецификаторах объявления которого содержится ключевое слово static. Ключевое слово static обычно появляется перед другими спецификаторами (поэтому синтаксис часто описывается неформально как static данные члена или static функция-член), но может появиться в любом месте последовательности спецификаторов.

Имя любого статического данных члена и статической функции-члена должно отличаться от имени содержащего класса.

Объяснение

Статические члены класса не связаны с объектами класса: они являются независимыми переменными со статическим или потоковым(с 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

Однако, если объявление использует constexpr или inline(с C++17) спецификатор, член должен быть объявлен с полным типом.

(с 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.

Статические данные члены класса в области видимости пространства имен имеют внешнюю связь, если сам класс имеет внешнюю связь (не является членом безымянного пространства имен). Локальные классы (классы, определенные внутри функций) и безымянные классы, включая вложенные классы безымянных классов, не могут иметь статические данные члены.

Статический данных член может быть объявлен inline. Встроенный статический данных член может быть определен в определении класса и может указать инициализатор. Ему не требуется определение вне класса:

struct X
{
    inline static int n = 1;
};
(с 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 объявлен constexpr , его необходимо инициализировать инициализатором, в котором каждое выражение является константным выражением, непосредственно внутри определения класса:

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)

Если const не-встроенный(с C++17) статический данных член или constexpr статический данных член(с C++11)(до C++17) используется в ODR-использовании, определение в области видимости пространства имен всё ещё требуется, но оно не может иметь инициализатор.

constexpr статический данных член подразумевается inline и не нуждается в повторном объявлении в области видимости пространства имен. Это повторное объявление без инициализатора (ранее требовалось) всё ещё допускается, но устарело.

(с 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++.

DR Применено к Поведение, как опубликовано Правильное поведение
CWG 194 C++98 (статические) имена функций-членов могут быть такими же, как у класса Добавлена ограничение на именование (включая
нестатические функции-члены)

Ссылки

  • Стандарт C++23 (ISO/IEC 14882:2023):
    • 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]

См. также

  • static спецификатор хранения

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/language/static

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API