Статические члены класса в C++

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

Извне доступ к статическим членам класса получается с помощью оператора доступа к члену пространства имён, где в качестве пространства имён выступает класс. При обращении к статическому члену класса используется оператор области видимости для того, чтобы идентифицировать тот класс, к которому принадлежит переменная. Внутри методов класса доступ к статическим членам класса осуществляется также как и ко всем остальным членам класса — просто указав название переменной (без оператора простраства имён и указания класса в качестве пространства имён).

В отличии от более новых и продвинутых Java, C#, PHP и прочих Си-подобных языков программирования, в олдскульном C++ со статическими переменными не всё так просто. Статические переменные класса C++ задаются чуть сложнее. В C++ нельзя просто взять и определить в классе статическую переменную, как это делается в вышеуказанных лангах программирования. В C++ все статические данные инициализируются нулями при создании первого объекта, и другая инициализация не предусмотрена. При объявлении статического члена данных класса этот член не определяется. Необходимо обеспечить для него определение вне класса в глобальном скопе и только так. Это делается путем нового объявления статической переменной. Это необходимо для того, чтобы под статическую переменную была выделена память. В общем, в C++ статическую переменную класса надо определять дважды — в классе и в глобальной области видимости, иначе никак. Причём дублировать объявление статической переменной можно только в глобальном скопе и больше нигде, ни в кострукторе, ни в списке инициализаци констурктора, ни где либо ещё, только в глобальном скопе.

Пример

class Counter {
	static int count;
	public:
	void setcount(int i) {count = i;};
	void showcount() {cout << count << " ";}
};
int Counter::count; // дублированное определение статичной переменной count
int main() {
	Counter a, b;
	a.showcount(); // выводит 0
	b.showcount(); // выводит 0
	a.setcount(10); // установка статического count в 10
	a.showcount(); // выводит 10
	b.showcount(); // также выводит 10
	return 0;
}

Статическая переменная count типа int объявляется в двух местах: в классе Counter и затем в глобальном скопе как переменная в пространсве имён (в классе) Counter. Borland C++ инициализирует count нулем. Именно поэтому первый вызов showcount() выводит в качестве результата нуль. Затем объект а устанавливает count равным 10. После этого оба объекта а и b выводят с помощью функции showcount() одну и ту же величину, равную 10. Поскольку существует только одна копия count, используемая совместно объектами а и b, то на экран выводится в обоих случаях значение 10.