Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции C++.doc
Скачиваний:
3
Добавлен:
01.05.2025
Размер:
1.44 Mб
Скачать

3.14 Статические члены класса

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

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

В качестве примера рассмотрим следующую программу:

#include <iostream.h>

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 объяв­ляется в двух местах: в классе counter и затем — как глобальная переменная. Компилятор иници­ализирует count нулем. Именно поэтому первый вызов showcount() выводит в качестве результата нуль. Затем объект а устанавливает count равным 10. После этого оба объекта а и b выводят с помощью функции showcount() одну и ту же величину, равную 10. Поскольку существует только одна копия count, используемая совместно объектами а и b, то на экран выводится в обоих слу­чаях значение 10.

ПАМЯТКА: Когда член класса объявляется статическим, тем самым определя­ется, что будет создаваться только одна копия этого члена, которая будет затем совместно использоваться всеми объектами этого класса.

Также можно иметь статические функции-члены. Статические функции-члены не могут прямо ссылаться на нестатические данные или нестатические функции, объявленные в их классе. Причи­ной тому является отсутствие для них указателя this, так что нет способа узнать, с какими именно нестатическими данными работать. Например, если имеется два объекта класса, содержащие стати­ческую функцию f(), и если f() пытается получить доступ к нестатической переменной var, опреде­ленной этим классом, то как можно определить, какую именно копию var следует использовать? Компилятор не может решить такую проблему. В этом заключается причина того, что статичес­кие функции могут обращаться только к другим статическим функциям или статическим данным. Также статические функции не могут быть виртуальными или объявляться с модификаторами const или volatile. Статическая функция может вызываться либо с использованием объекта класса, либо с использованием имени класса и оператора области видимости. Тем не менее, не надо забы­вать, что даже при вызове статической функции с использованием объекта, ей не передается указатель this.

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

#include <iostream.h>

enum access_t { shared, in_use, locked, unlocked };

class access

{

static enum access_t acs; // . . . public:

static void set_access(enum access_t a) { acs = a; }

static enum access_t get_access() { return acs; }

};

enum access_t access::acs; // определение acs

int main()

{

access obj1, obj2;

access::set_access(locked); // вызов с использованием имени класса

// ... код

// может ли obj2 обращаться к ресурсу

if(obj2.get_access()==unlocked)

{

access::set_access(in_use); // вызов с помощью имени класса

cout << "Access resource.\n";

}

else cout << "Locked.\n";

return 0;

}

При запуске этой программы на экране появится «Locked». Обратим внимание, что функция set_access() вызвана с именем класса и оператором области видимости. Функция get_access() вы­звана с объектом и оператором «точка». При вызове статической функции может использовать­ся любая из этих форм и обе они дают одинаковый эффект.

Как отмечалось, статические функции имеют прямой доступ только к другим статическим фун­кциям или статическим данным в пределах одного и того же класса. В приведенном выше примере статические функции set_access() и get_access() работают только со статической переменной acs.