Шаг 220 - Обобщение шагов 215-219

Посмотрев предыдущие шаги Вы могли подумать, что это полный ад. Куча макросов неизвестно зачем и почему. Для полного понимания всего сказанного в этих шагах мне кажется нужно думать так.

Любое приложение или структура данных состоит из многих объектов. Эти объекты нужно уметь объединять в массивы или коллекции. Ну, например, Окно диалоговой панели вмещает в себя много элементов разных типов: всяческие кнопки, элементы редактирования, статический текст и так далее. Вам нужно работать со всеми элементами сразу. Например, запустив механизм DDX или перерисовывая экран. То есть должен быть набор указателей на эти объекты. В C++ есть проверка типов и поэтому все становится намного сложнее. Давайте рассмотрим теоритический массив. Вот такой

x_type* p1
x_type* p2
......

То есть нам нужен универсальный указатель на любой класс. Он есть и назван CRuntimeClass. Вот теперь какой наш массив

CRuntimeClass* p1;
CRuntimeClass* p2
......

Теперь в этот массив нужно помещать классы. Можно поступить просто указывать ссылку на созданные нами объекты и самим следить за расположением их в памяти и удалением. Это не удобно. Кроме того есть набор классов логически связанных, которые и появляються вместе и изчезают, ну например, шаблон приложения.

CSingleDocTemplate* pDocTemplate;
pDocTemplate = new CSingleDocTemplate(
	IDR_MAINFRAME,
	RUNTIME_CLASS(CMy11Doc),
	RUNTIME_CLASS(CMainFrame),       
	RUNTIME_CLASS(CMy11View));
AddDocTemplate(pDocTemplate);

Соответственно класс указателя CRuntimeClass должен уметь сам строить классы заменяя new и он это умеет, т.к. у него есть CreateObject. Только построение объекта делится на два шага: первое - это получение информации о нем и второе - непосредсвенное построение. В стандарте C++ нет механизма для динамического определения типа класса. Значит этот механизм будет надстройкой. Значит классы, которые будут динамически создаваться надо специально определить. Так вот добавляя в класс DECLARE_DYNAMIC мы создаем в классе информацию о его типе. Все. Теперь мы можем определить тип класса. Для этого есть функция IsKindOf. Имея информацию о типе можно говорить о создании. Но создание класса на основе информации о типе тоже не является стандартом. Для того, чтобы класс можно было создавать динамически надо ему дать эту возможность. Это мы делаем добавляя макрос DECLARE_DYNCREATE. Применяя второй макрос мы автоматически применяем первый, так как без информации объект нельзя создать.

ИМЯ -> CRuntimeClass        RUNTIME_CLASS(имя)
CRuntimeClass -> ИМЯ	    IsKindOf(CRuntimeClass)	
// Достаточно DECLARE_DYNAMIC
Создать объект		    CRuntimeClass->CreateObject
// ТОлько при DECLARE_DYNCREATE

Понятно я объяснил причины или нет ? Незнаю. Давайте попробую сказать коротко. Возможности описанные в шагах 215-219 созданы для того, чтобы в одном массиве или коллекции можно было хранить объекты разных типов.


Предыдущий Шаг | Следующий Шаг | Оглавление
Автор Каев Артем - 17.08.2000