C++/Ключевые слова/static

Материал из Энциклопедия о программировании
Перейти к: навигация, поиск

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

Использование

Ключевое слово static очень многогранно, оно имеет много синтаксических значений в языке.

Ключевое слово static можно использовать в следующих случаях:

  • При объявлении переменной или функции в области видимости файла (в глобальной области видимости и/или области видимости пространства имен) ключевое слово static указывает, что переменная или функция имеет внутреннюю компоновку. При объявлении переменной она имеет статическую длительность и компилятор инициализирует её со значением 0, если не указано другое значение.
  • При объявлении переменной в функции ключевое слово static указывает, что переменная сохраняет свое состояние между вызовами этой функции.
  • При объявлении данных-члена в объявлении класса ключевое слово static указывает, что всеми экземплярами этого класса совместно используется одна копия этого члена. Статические данные-член должны быть определены в области видимости файла. Целочисленные данные-члены, объявляемые как const static, могут иметь инициализатор.
  • При объявлении функции-члена в объявлении класса ключевое слово static указывает, что эта функция совместно используется всеми экземплярами данного класса. Статическая функция-член не может получать доступ к члену экземпляра, поскольку она не имеет неявного указателя this. Для доступа к члену экземпляра следует объявить функцию с параметром, являющимся указателем или ссылкой на экземпляр.
  • Объявление членов объединения как статических невозможно. Однако, объединение, которое глобально объявлено анонимным, должно быть явно объявлено как static.

Static в процедурном программировании

В процедурном программировании ключевое слово static в C++ локализует всё в пределе одного модуля (файла).

По-умолчанию объект или переменная, определенные вне всех блоков, имеют статическую длительность и внешнюю компоновку. Статическая длительность означает, что объект или переменная размещается в памяти при запуске программы, а освобождает память, когда программа завершается. Внешняя компоновка означает, что имя переменной видно за пределами файла, в котором эта переменная объявлена. Внутренняя компоновка означает, что имя не видно за пределами файла, в котором объявлена переменная.

Static функции

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

Static переменные

Глобальные static переменные работают точно также как и функции.

Static переменные внутри функции (метода) инициализируются один раз и после выхода их функции они хранятся на стеке.

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

Static в ООП

Объявленные внутри классов статические сущности не участвуют в динамике, т.е. они просто находятся в пространстве имён класса и не принадлежат объектам класса.

  • Объявить статические переменные в конструкторе нельзя.
  • При внешнем объявлении переменной в классе ключевое слово static не требуется, т.к. это само собой разумеется т.к. это вытекает из самой парадигмы ООП.
  • При инициализации переменной извне, также как и при реализации метода, тип переменной всё равно приходится указывать повторно, несмотря на то, что он уже указан при описании класса в заголовочном файле.

Примеры

Статическая переменная:

class ClassName {
  static int counter;
};
static int ClassName::counter = 0;

Инициализация статического вектора:

class Foo {
public:
	static std::vector<bool> vec1;
	static std::vector<int> vec2;
	static std::vector<std::vector<int>> vec3;
	static const std::vector<int> vec4;
};
static std::vector<int> Foo::vec1 = {true, false, true};
static std::vector<int> Foo::vec2 = list_of(3)(5)(10); // arr of values 3, 5, 10
static std::vector<std::vector<int>> Foo::vec3 = { {4, 8, 3}, {17, 5, 10}, {20, 55, 100} };
static const std::vector<int> Foo::vec4 = {4, 17, 20};

Инициализация статических массивов:

struct Foo {
	static const int array[];
	static std::vector<int> vec;
};
static const int Foo::array[] = { 1, 10, 100, 1000, 10000, 42 };
static std::vector<int> Foo::vec(array, array + sizeof(array)/sizeof(*array));

Ссылки

Шаблон:C++