Алекс Jenter - Программирование на Visual C++. Архив рассылки

Тут можно читать онлайн Алекс Jenter - Программирование на Visual C++. Архив рассылки - бесплатно полную версию книги (целиком) без сокращений. Жанр: comp-programming. Здесь Вы можете читать полную версию (весь текст) онлайн без регистрации и SMS на сайте лучшей интернет библиотеки ЛибКинг или прочесть краткое содержание (суть), предисловие и аннотацию. Так же сможете купить и скачать торрент в электронном формате fb2, найти и слушать аудиокнигу на русском языке или узнать сколько частей в серии и всего страниц в публикации. Читателям доступно смотреть обложку, картинки, описание и отзывы (комментарии) о произведении.
  • Название:
    Программирование на Visual C++. Архив рассылки
  • Автор:
  • Жанр:
  • Издательство:
    неизвестно
  • Год:
    неизвестен
  • ISBN:
    нет данных
  • Рейтинг:
    4.33/5. Голосов: 91
  • Избранное:
    Добавить в избранное
  • Отзывы:
  • Ваша оценка:
    • 80
    • 1
    • 2
    • 3
    • 4
    • 5

Алекс Jenter - Программирование на Visual C++. Архив рассылки краткое содержание

Программирование на Visual C++. Архив рассылки - описание и краткое содержание, автор Алекс Jenter, читайте бесплатно онлайн на сайте электронной библиотеки LibKing.Ru

РАССЫЛКА ЯВЛЯЕТСЯ ЧАСТЬЮ ПРОЕКТА RSDN, НА САЙТЕ КОТОРОГО ВСЕГДА МОЖНО НАЙТИ ВСЮ НЕОБХОДИМУЮ РАЗРАБОТЧИКУ ИНФОРМАЦИЮ, СТАТЬИ, ФОРУМЫ, РЕСУРСЫ, ПОЛНЫЙ АРХИВ ПРЕДЫДУЩИХ ВЫПУСКОВ РАССЫЛКИ И МНОГОЕ ДРУГОЕ.

Программирование на Visual C++. Архив рассылки - читать онлайн бесплатно полную версию (весь текст целиком)

Программирование на Visual C++. Архив рассылки - читать книгу онлайн бесплатно, автор Алекс Jenter
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать
Регистрация типов

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

Хоть это и неочевидно, именно макрос IMPLEMENT_DYNCREATE позволяет пользователям без проблем добавлять новые классы в реестр. После развертывания IMPLEMENT_DYNCREATE, как показано на листинге 2, статическая структура CRuntimeClass в CScribDoc инициализируется так, как показано в примере 3.

Листинг 2

void__stdcall CScribDoc::Construct(void* p) {

new(p) CScribDoc;

}

CRuntimeClass* __stdcall CScribDoc::_GetBaseClass() {

return (&CDocument::classCDocument);

}

CRuntimeClass CScribDoc::classCScribDoc = {

"CScribDoc", sizeof(CScribDoc), 0xFFFF, CScribDoc::Construct,

&CScribDoc::_GetBaseClass, 0 };

static const AFX_CLASSINIT _init_CScribDoc(&CScribDoc::classCScribDoc);

CRuntimeClass* CScribDoc::GetRuntimeClass() const {

return &CScribDoc::classCScribDoc;

}

Пример 3: Инициализация статической структуры CRuntimeClass в CScribDoc.

CRuntimeClass CScribDoc::classCScribDoc = {

"CScribDoc", sizeof(CScribDoc), 0xFFFF, CScribDoc::Construct, &CScribDoc::GetBaseClass, 0

};

Некоторые из элементов этой структуры мы уже рассматривали. В частности, выражение sizeof(CScribDoc) используется CreateObject для выделения нужного объема памяти; затем эта память инициализируется функцией, на которую указывает CScribDoc::Construct .

Такой механизм делает возможной регистрацию типов объектов на лету каждый раз, когда они линкуются с программой, решая, таким образом, Проблему 2.

Часто разработчики задаются вопросом – в чем разница между различными макросами DECLARE и IMPLEMENT? Все макросы DECLARE_DYNAMIC и IMPLEMENT_DYNAMIC определяют статическую структуру CRuntimeClass , подобно DYNCREATE, описанному ранее, за одним исключением – поле Construct в этой структуре установлено в NULL. DECLARE_DYNCREATE и IMPLEMENT_DYNCREATE передают в структуру адрес функции Construct() для динамического создания типа. DECLARE_SERIAL и IMPLEMENT_SERIAL основываются на макросах DYNCREATE, но заменяют поле со значением 0xFFFF на номер схемы этой структуры.

Макросы SERIAL также определяют для класса operator>> . Этот оператор требует особого подхода, так как ему передается указатель на класс, но ни один из экземпляров этого класса не будет существовать, пока экземпляр не будет загружен из файла. Без экземпляра класса, MFC не может получить доступ к информации о классе времени выполнения для проверки на то, что загружаемый объект является объектом того же класса (или класса-наследника), что и переданный указатель. Перегружая operator>> , MFC получает возможность передавать указатель на информацию о типе времени выпонения, чтобы механизм сериализации не зависел от типа (typesafe serialization).

Создание типов из файла

Третья проблема состоит в том, чтобы создать механизм сопоставления для создания типов по информации, прочитанной из файла. Учитывая то, что компилятор требует уникальности имен классов и то, что имя класса уже включено в структуру CRuntimeClass , имя класса является идеальным кандидатом на запись в файл и последующую идентификацию класса.

Итак, при сохранении объекта в архиве можно записать туда имя класса и его данные. MFC так и делает, плюс проводит дополнительную работу для каждого сериализуемого класса. Имя класса берется из структуры CRuntimeClass , которая возвращается виртуальной функцией объекта. Определение типа производится динамически во время выполнения, поэтому структура типа Tiger будет корректно записана даже в случае, если MFC передается указатель на ее базовый класс типа Animal . Эта типонезависимость очень важна. Любая функция может без опасений сохранить объект в архиве, даже если точный тип объекта неизвестен.

То же касается и восстановления объекта из архива. Возвращаясь к примеру в начале статьи, несколько простых выражений из примера 4 заставляют MFC успешно загружать корректный тип документа из файла.

Пример 4: Загрузка правильного типа документа из файла.

CDocument* pDoc;

CArchive& ar;

ar >> pDoc;

В реализации operator>> MFC загружает из файла имя класса, и ищет это имя в списке типов. Если этот тип присутствует в реестре и был описан либо как DECLARE_DYNCREATE, либо как DECLARE_SERIAL, MFC может сконструировать требуемый объект. Непосредственная загрузка данных этого объекта возлагается на сам объект вызовом его виртуальной функции Serialize() , что решает Проблему 3.

Тип создаваемого объекта не привязан к типу запрошенного объекта. Если класс-потомок загружается через указатель на класс-предок, как в примере с CDocument , все равно создастся корректный класс-потомок. Это единственный способ корректно задать указатель vtbl так, чтобы он указывал на виртуальные функции объекта. Если объект в архиве не является "родственником" запрошенного объекта, MFC взведет исключение.

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

Оптимизация архивов

Когда я впервые просматривал этот код, мне виделись распухшие файлы с объектами и большие задержки при постоянном просмотре связанного списка. Но архивы MFC остаются маленькими, а скорость выполнения высокой благодаря хэш-идентификаторам.

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

Такое поведение также означает, что множественные ссылки на один и тот же объект обрабатываются корректно. Если объекты A и B при создании архива содержат указатели на один объект C, они оба будут указывать на один объект C после восстановления их из архива. MFC также корректно восстановит циклические меж-объектные ссылки.

В результате все работает гораздо быстрее, чем я ожидал. На 486/66, MFC смогла сохранить и восстановить архив размером более мегабайта с 10000 экземплярами CArray менее, чем за 2 секунды.

Есть одно важное ограничение – хэш-таблица не может содержать больше 32766 классов и объектов в контексте одного архива. Это число включает в себя только классы, унаследованные от CObject и сериализуемые оператором operator<<, и не включает фундаментальные типы, например, short и long , CString и CPoint . (за дополнительной информацией о конструировании архивов обратитесь к MFC Technical Note 2: Persistent Object Data Format ).

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать


Алекс Jenter читать все книги автора по порядку

Алекс Jenter - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки LibKing.




Программирование на Visual C++. Архив рассылки отзывы


Отзывы читателей о книге Программирование на Visual C++. Архив рассылки, автор: Алекс Jenter. Читайте комментарии и мнения людей о произведении.


Понравилась книга? Поделитесь впечатлениями - оставьте Ваш отзыв или расскажите друзьям

Напишите свой комментарий
x