- •3.1. Определение класса
- •Int Left;
- •Int Right;
- •Int Bottom;
- •3.2. Создание экземпляра класса
- •Int Left;
- •Int Right;
- •Int Bottom;
- •3.3. Доступ к членам класса
- •Int Left;
- •Int Right;
- •Int Bottom;
- •3.4. Инкапсуляция
- •Int Left;
- •Int Right;
- •Int Bottom;
- •Int Left;
- •Int Right;
- •Int Bottom;
- •Int Left;
- •Int Right;
- •Int Bottom;
- •3.5. Конструкторы и деструкторы
- •3.5.1. Конструкторы
- •Int Left;
- •Int Right;
- •Int Bottom;
- •Int Left;
- •Int Right;
- •Int Bottom;
- •Int Left;
- •Int Right;
- •Int Bottom;
- •3.5.2. Деструкторы
- •3.5.3. Когда вызываются конструкторы и деструкторы
- •3.6. Встроенные функции-члены
- •Int Left;
- •Int Right;
- •Int Bottom;
- •3.7. Организация исходных файлов
- •Int Left;
- •Int Right;
- •Int Bottom;
- •3.8. Указатель this
- •3.9. Статические члены класса
3.9. Статические члены класса
Обычно экземпляр класса имеет собственную копию переменных-членов, принадлежащих классу. Однако, если переменная-член объявлена с использованием спецификатора static, возможно существование единственной копии этой переменной-члена независимо от того, сколько экземпляров класса создается (даже если не создается ни одного экземпляра). Например, следующий класс определен как статическая переменная Count.
class CTest
{
public:
static int Count;
// остаток определения класса ...
}
Независимо от того, сколько создается экземпляров класса CTest, для переменной-члена Count существует единственная копия.
В дополнение к объявлению статической переменной внутри класса, ее необходимо также определить и инициализировать снаружи, как глобальную переменную-член. Так как определение статических переменных помещено вне класса, необходимо описать класс, в котором они объявлены, используя операцию расширения области видимости (в этом примере CTest::). Например, можно определить и инициализировать переменную Count следующим образом.
// вне любого класса или функции
int CTest::Count = 0;
Поскольку статические переменные-члены класса существуют независимо от любого объекта класса, к ним можно получить доступ, используя имя класса и оператор расширения области видимости без ссылки на экземпляр класса, как показано в следующем примере.
void main()
{
CTest::Count = 1;
// ...
}
Статическую переменную можно воспринимать как нечто среднее между глобальной переменной и данными обычного типа, принадлежащими классу. Подобно глобальной переменной, такая переменная определяется и инициализируется вне функции. Фактически, она представляет единичную область памяти, которая существует на протяжении жизни всей программы. Однако, как и обычные переменные класса, она объявляется внутри класса, а доступ к ней может быть управляемым (т.е. открытым, закрытым или защищенным).
Можно также определить функцию-член класса с использованием спецификатора static, например:
class CTest
{
// ...
static int GetCount ()
{
// код функции ...
}
// ...
}
Статическая функция-член класса имеет следующие свойства.
-
Программный код вне класса может вызвать функцию с использованием имени класса и оператора расширения области видимости без ссылки на экземпляр класса, который не нужен, даже если он существует, например:
void main ()
{
int Count = CTest::GetCount ();
// .. .
}
-
Статическая функция-член непосредственно может ссылаться только на статические переменные и статические функции, принадлежащие ее классу. Так как эту функцию можно вызвать без ссылки на экземпляр класса, статическая функция-член не имеет указателя this, содержащего адрес объекта. Следовательно, если она пытается получить непосредственный доступ к нестатическим переменным-членам, компилятор не сможет определить, какому объекту принадлежат переменные-члены.
Статические переменные-члены и функции-члены могут использоваться для хранения переменной, применяемой всем классом, или переменной, общей для всех экземпляров класса. Следующая программа иллюстрирует использование статических элементов для подсчета текущего количества экземпляров класса.
include <iostream.h>
class CTest
{
private:
static int Count;
public:
CTest ()
{
++Count;
}
~CTest ()
{
--Count;
}
static int GetCount ()
{
return Count;
};
};
int CTest::Count = 0;
void main ()
{
cout « CTest::GetCount () << " objects exist\n";
CTest Testl;
CTest *PTest2 = new CTest;
cout << CTest::GetCount () << " objects exist\n";
delete PTest2;
cout « CTest::GetCount 0 « " objects exist\n "
}
В результате будет напечатано следующее.
0 objects exist
2 objects exist
1 objects exist