С++ - язык, который изучается постепенно.Информация о классе
                   Справочники Всё для создания сайта

Ссылки


Home
Бизнес
Справочники
Советы







Материалы книги получены с http://www.itlibitum.ru/

Информация о классе

В объектах класса удобно хранить сведения о самом классе. Для этого лучше всего создать гомоморфный базовый класс для объектов классов.

class Class {

protected:

Collection<Class> base_classes;

Collection<Class> derived_classes;

String class_name;

Class() {}; // Класс становится абстрактным базовым

public:

// Функции доступа для получения имени и т.д.

};

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

Имя класса и создание экземпляров по имени

Базовая информация, которую может сообщить объект класса, - имя класса в виде некоторой символьной строки. Кроме того, можно хранить словарь всех объектов классов, индексируемый по имени класса. Если добавить к этому универсальный интерфейс к производящей функции, вам удастся реализовать возможность, которая не поддерживается в С++ напрямую - создание экземпляров по имени (instantiate by name).

// Где-то в клиентской программе

Class* c = gClasses.Find("Grandpa");

???* g = (Grandpa*)c->make(???);

Как видите, практическая польза такого подхода ограничивается некоторыми проблемами. Если мы уже знаем, что создается экземпляр Grandpa, то создание экземпляра по имени выглядит неразумно - нам будет трудно определить, к какому классу выполняется преобразование. Вдобавок данная схема не позволяет предоставить отдельные сигнатуры для производящих функций производных классов. Тем не менее, в некоторых ситуациях такая методика оказывается чрезвычайно полезной. Предположим, вы сохранили объект в виде потока байтов и теперь загружаете его. Если первые n байт содержит имя класса в виде символьной строки, вы сможете найти нужный объект класса для создания экземпляра.

Как правило, реализация заканчивается созданием во всех классах Class функции make(istream&) или ее эквивалента. Программа приобретает следующий вид:

// В коде чтения потока

cin << className;

Class* c = gClasses.Find(className);

BasClass* obj = c->make(cin);

Иерархия классов

Сведения об иерархии классов можно хранить по разному, но в конечном счете все сводится к структурам данных с экземплярами Class. Выше был представлен один из вариантов: вести в каждом Class две коллекции, по одной для базовых и производных классов. Конечно, это следует понимать условно - речь идет об иерархии не объектов Class, а представленных ими классов. Необходимость различать понятия Class и «класс» наверняка вызовет у вас головную боль, но у поклонников SmallTalk и Lisp это считается хорошим развлечением и признаком мастерства. Другой способ - ввести одну глобальную структуру данных с парами (базовый, производный), индексируемую в обоих

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

Описания переменных класса

В некоторых ситуациях объекты Class стоит сделать достаточно умными, чтобы они могли получать экземпляры представляемого класса и описывать их структуру. Все начинается с переменных класса. В наиболее прямолинейном варианте Class возвращает итератор, который в свою очередь возвращает пару смещение/Class, описывающую смещение переменной внутри экземпляра и ее Class. Имеет смысл создать перечисления для трех подмножеств переменных класса:

1. Все переменные, включая встроенные типы (такие как int). Для представления примитивных типов вам придется создать фиктивные классы, производные от Class.

2. Только переменные невстроенных типов, для которых обычно и так существует свой Class.

3. Только указатели и ссылки на другие объекты.

Последний вариант играет особенно важную роль в некоторых нетривиальных алгоритмах сборки мусора.

Описания функций класса

В еще более редких ситуациях объект Class должен описывать набор функций представленного им класса. При этом вы фактически начинаете играть роль компилятора С++, так что не перегибайте палку. И снова оптимальным представлением оказывается итератор. Для каждой функции можно возвращать любую информацию, от простейшей (ее имени) до более сложной (адрес, имена, типы и порядок аргументов и тип возвращаемого значения). Некоторые проблемы просто выходят за рамки С++; если вам захочется проделать нечто подобное, стоит серьезно подумать об использовании настоящего динамического языка.

Коллекции экземпляров

Класс Class предоставляет еще одну интересную возможность - ведение коллекции всех

экземпляров класса. Это может быть либо отдельная коллекция для каждого Class, либо одна глобальная структура данных с парами (Class, экземпляр). Если выбран второй вариант и коллекция индексируется в обоих направлениях, она оказывается чрезвычайно полезной при отладке Покажи мне все экземпляры класса x»), а также может применяться для ответов на вопросы вроде «Каков класс данного экземплярабез физического хранения адреса объекта Class в каждом экземпляре. Такое решение работает только для экземпляров верхнего уровня, создаваемых производящими функциями; вложенные объекты (переменные или базовые классы) в этот реестр не попадут.

Статистика

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


Назад    Содержание    Далее    

Home  Создание сайтов  Учебник по записи CD  Справочник Web дизайнера Самоучитель IE PHP и MySQL Компьютерные сети С++ E-mail me

Copyright 2007. Климов Александр. All Right Reserved.
Hosted by uCoz