static
members
Внутри определения класса ключевое слово static объявляет члены, которые не привязаны к экземплярам класса.
Вне определения класса это имеет другое значение: см. storage duration .
СодержаниеСинтаксисОбъявление статического члена — это объявление члена, спецификаторы объявления которого содержат ключевое слово Имя любого статического элемента данных и статической функции-члена должно отличаться от имени содержащего класса. ОбъяснениеСтатические члены класса не связаны с объектами класса: они являются независимыми переменными со статической или поточной (начиная с C++11) продолжительностью хранения или обычными функциями. Ключевое слово static используется только при объявлении статического члена внутри определения класса, но не при определении этого статического члена: class X { static int n; }; // объявление (использует 'static') int X::n = 1; // определение (не использует 'static') Объявление внутри тела класса не является определением и может объявлять член как неполный тип (кроме void ), включая тип, в котором объявлен член: struct Foo; struct S { static int a[]; // объявление, неполный тип static Foo x; // объявление, неполный тип static S s; // объявление, неполный тип (внутри собственного определения) }; int S::a[10]; // определение, полный тип struct Foo {}; Foo S::x; // определение, полный тип S S::s; // определение, полный тип
Для обращения к статическому члену
struct X { static void f(); // объявление static int n; // объявление }; X g() { return X(); } // некоторая функция, возвращающая X void f() { X::f(); // X::f - квалифицированное имя статической функции-члена g().f(); // g().f - выражение доступа к члену, ссылающееся на статическую функцию-член } int X::n = 7; // определение void X::f() // определение { n = 1; // X::n доступен как просто n в этой области видимости } Статические члены подчиняются правилам доступа к членам класса (private, protected, public) . Статические функции-членыСтатические функции-члены не связаны с каким-либо объектом. При вызове у них отсутствует this указатель. Статические функции-члены не могут быть virtual , const , volatile , или ref-qualified . Адрес статической функции-члена может быть сохранён в обычном указателе на функцию , но не в указателе на функцию-член . Статические элементы данныхСтатические элементы данных не связаны ни с каким объектом. Они существуют, даже если не было определено ни одного объекта класса. Во всей программе существует только один экземпляр статического элемента данных со статическим временем хранения, если только не используется ключевое слово thread_local, в этом случае для каждого потока существует один такой объект с временем хранения потока(начиная с C++11). Статические элементы данных не могут быть Статические элементы данных класса в области видимости пространства имен имеют внешнюю компоновку, если сам класс имеет внешнюю компоновку (не является членом безымянного пространства имен). Локальные классы (классы, определенные внутри функций) и неименованные классы, включая классы-члены неименованных классов, не могут иметь статические элементы данных.
Константные статические членыЕсли статический элемент данных целочисленного или перечислимого типа объявлен const (и не volatile ), он может быть инициализирован с помощью инициализатора , в котором каждое выражение является константным выражением , непосредственно внутри определения класса: struct X { const static int n = 1; const static int m{2}; // начиная с C++11 const static int k; }; const int X::k = 3;
Если константный не-inline (since C++17) статический член данных или constexpr статический член данных (since C++11) (until C++17) подвергается ODR-использованию , определение в области видимости пространства имён всё ещё требуется, но оно не может иметь инициализатора.
struct X { static const int n = 1; static constexpr int m = 4; }; const int *p = &X::n, *q = &X::m; // X::n и X::m являются ODR-используемыми const int X::n; // … поэтому определение необходимо constexpr int X::m; // … (кроме X::m в C++17) Ключевые словаОтчеты о дефектахСледующие отчеты об изменениях в поведении, являющиеся дефектными, были применены ретроактивно к ранее опубликованным стандартам C++.
Ссылки
Смотрите также |