Посмотрев предыдущие шаги Вы могли подумать, что это полный ад. Куча макросов неизвестно зачем и почему. Для полного понимания всего сказанного в этих шагах мне кажется нужно думать так.
Любое приложение или структура данных состоит из многих объектов. Эти объекты нужно уметь объединять в массивы или коллекции. Ну, например, Окно диалоговой панели вмещает в себя много элементов разных типов: всяческие кнопки, элементы редактирования, статический текст и так далее. Вам нужно работать со всеми элементами сразу. Например, запустив механизм 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 созданы для того, чтобы в одном массиве или коллекции можно было хранить объекты разных типов.