Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
КРАТКИЙ ОБЗОР С.doc
Скачиваний:
1
Добавлен:
26.10.2018
Размер:
2.11 Mб
Скачать

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

      Класс - это тип, а не некоторое данное, и для каждого объекта       класса создается своя копия членов, представляющих данные. Однако,       наиболее удачная реализация некоторых типов требует, чтобы все       объекты этого типа имели некоторые общие данные. Лучше, если эти       данные можно описать как часть класса. Например, в операционных       системах или при моделировании управления задачами часто нужен       список задач:       class task {       // ...       static task* chain;       // ...       };       Описав член chain как статический, мы получаем гарантию, что       он будет создан в единственном числе, т.е. не будет создаваться       для каждого объекта task. Но он находится в области видимости       класса task, и может быть доступен вне этой области, если только       описан в общей части. В этом случае имя члена должно уточняться       именем класса:       if (task::chain == 0) // какие-то операторы       В функции-члене его можно обозначать просто chain. Использование       статических членов класса может заметно сократить потребность в       глобальных переменных.       Описывая член как статический, мы ограничиваем его область       видимости и делаем его независимым от отдельных объектов его       класса. Это свойство полезно как для функций-членов, так и для       членов, представляющих данные:       class task {       // ...       static task* task_chain;       static void shedule(int);       // ...       };       Но описание статического члена - это только описание, и где-то       в программе должно быть единственное определение для описываемого       объекта или функции, например, такое:       task* task::task_chain = 0;       void task::shedule(int p) { /* ... */ }       Естественно, что и частные члены могут определяться подобным образом.       Отметим, что служебное слово static не нужно и даже нельзя       использовать в определении статического члена класса. Если бы оно       присутствовало, возникла бы неоднозначность: указывает ли оно на то,       что член класса является статическим, или используется для       описания глобального объекта или функции?       Слово static одно из самых перегруженных служебных слов в С       и С++. К статическому члену, представляющему данные, относятся       оба основных его значения: "статически размещаемый" , т.е.       противоположный объектам, размещаемым в стеке или свободной памяти,       и "статический" в смысле с ограниченной областью видимости, т.е.       противоположный объектам, подлежащим внешнему связыванию. К       функциям-членам относится только второе значение static.

5.4.5 Указатели на члены

      Можно брать адрес члена класса. Операция взятия адреса функции-члена       часто оказывается полезной, поскольку цели и способы применения       указателей на функции, о которых мы говорили в $$4.6.9, в равной       степени относятся и к таким функциям. Указатель на член можно получить,       применив операцию взятия адреса & к полностью уточненному имени       члена класса, например, &class_name::member_name. Чтобы описать       переменную типа "указатель на член класса X", надо использовать       описатель вида X::*. Например:       #include <iostream.h>       struct cl       {       char* val;       void print(int x) { cout << val << x << '\n'; }       cl(char* v) { val = v; }       };       Указатель на член можно описать и использовать так:       typedef void (cl::*PMFI)(int);       int main()       {       cl z1("z1 ");       cl z2("z2 ");       cl* p = &z2;       PMFI pf = &cl::print;       z1.print(1);       (z1.*pf)(2);       z2.print(3);       (p->*pf)(4);       }       Использование typedef для замены трудно воспринимаемого описателя       в С достаточно типичный случай. Операции .* и ->* настраивают       указатель на конкретный объект, выдавая в результате функцию,       которую можно вызывать. Приоритет операции () выше, чем у операций       .* и ->*, поэтому нужны скобки.       Во многих случаях виртуальные функции ($$6.2.5) успешно       заменяют указатели на функции.