![]() Студопедия КАТЕГОРИИ: АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция |
Сериализация объекта StringData
Класс документа (файл writerDoc.cpp) содержит встроенный метод Serlalize(), который выглядит следующим образом: void CWriterDoc::Serialize(CArchive& ar) { if (ar.IsStoring()) { // TODO: добавьте код сохранения } else { // TODO: добавьте код загрузки } } Именно в этом методе должна происходить сериализация объекта StringData. Методу Serialize() передается ссылка на объектаrкласса CArchive (вообще говоря, ссылка содержит адрес объекта, но в программе ее можно использовать как обычный объект); работа с объектом аrпрактически не отличается от работы с потоками coutи cin. Сначала мы вызываем метод IsStoring()объекта аг, чтобы узнать, был ли метод вызван для записи на диск; в этом случае сериализация StringData выполняется так: void CWriterDoc::Serialize(CArchive& ar) { if (ar.IsStoring()) { ar<<StringData; } else { // TODO: добавьте код загрузки } } Если же потребуется загрузить объект StringData с диска, будет использована другая строка программы: void CWriterDoc::Serialize(CArchive& ar) { if (ar.IsStoring()) { ar<<StringData; } else { ar>>StringData; } } В принципе это все, что нужно, но мы добавим последний штрих— когда пользователь заносит в объект StringData новые символы, мы сообщаем документу об изменении данных. Если пользователь захочет выйти из программы, не сохранив данные, программа выведет хорошо знакомое всем пользователям Windows диалоговое окно с предложением сохранить изменения в документе. Чтобы сообщить приложению об изменении данных, мы вызовем в OnChar() метод объекта документаSetModifiedFlag(): void CWriterView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) { CWriterOoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); pDoc->StringData += nChar; Invalidate(); pDoc->SetModifiedFlag(); CView::OnChar(nChar, nRepCnt, nFlags); } ПОДСКАЗКА: Флаг изменения документа сбрасывается, когда пользователь сохраняет документ на диске. Запустите программу. На рисунке показан текст, введенный в программу и готовый к сохранению на диске. Когда пользователь выбирает в меню команду File > Save As, открывается диалоговое окно Save As. Мы сохраним данные программы в виде файлаtext.dat. После сохранения пользователь может снова прочитать файл командой File > Open, которая открывает диалоговое окно Open. Выбранный файл text.dat загружается в программу. Содержимое загруженного файла отображается в окне. При загрузке файла и изменении документа вид объявляется недействительным, поэтому пpoисходит его автоматическое обновление с выводом содержимого нового документа. Обратите внимание на то, что вместо Untitled- writerв заголовке окна теперь находится строка text.dat - writer. Таким образом, программа сообщает польэователю имя текущего документа. В программу осталось внести еще пару изменений. При создании нового документа командой File > New следует стареть старое содержимое StringData. Мы сдeлаем это в методе OnNewDocument ()документа. В данный момент он выглядит так (обратите внимание на вызов метода UpdateAllViews() - как мы увидим далее, он приводит к обновлению всех видов программы новыми данными документа): BOOL CWriterOoc:;OnNewDocument() { if (!CDocument::OnNewDocument()) return FALSE; // TODO: добавьте код повторной инициализации //(документы SDI повторно используют документ) UpdateAllViews(NULL); return TRUE; } Содержимое объекта StringData при создании нового документа стирается следующим образом: BOOL CWriterOoc::OnNewDocument() { if (!CDocument::OnNewDocument()) return FALSE; // TODO: добавьте код повторной инициализации //(документы SDI повторно используют документ) StringData = ""; return TRUE; } В результате команда Newв меню Fileстановится активной. Есливам потребуется выполнить сериализацию для нескольких объектов, относящихся к различным классам, проблема решается просто — достаточно загрузить их в том же порядке, в котором они были сохранены: void CWriterDoc::Serialize(CArchive& ar) { if (ar.IsStoring()) { ar << Data1; ar <<Data2; } else { ar>> Data1; ar>>Data2; } } Такой подход позволяет сохранить и восстановить сразу несколько объектов вместо одного. Описанная выше методика работает для объектов классов, поставляемых с Visual C++. Но что делать, если в программе используются нестандартные классы? Давайте посмотрим, как выполняется сериализация для них. Сериализация нестандартных объектов Предположим, мы создали новый класс CData и хотим организовать сериализацию его объектов. Допустим, класс содержит строковый объект data: class Data { private: CString data; } Кроме того, есть конструктор, в котором данный объект инициализируется пустой строкой, а также три метода для работы со строкой: AddText()для добавления текста в конец строки, DrawText() для рисования текста в контексте устройства иClearText()для очистки строки (обратите внимание: тело методов можно определять в объявлении класса — это называется встроенный(inline) определением): class Data { private: CString data; public: CData(){data = CString("");} void AddText(CString text){data += text;} void DrawText(CDC* pDC){pDC->TextOut(0, 0, data);} void ClearText(){data = ""} } Нам предстоит организовать сериализацию ддя объектов этого класса. Создайте новую однодокументную (SDI) программу seriatizer. Затем выполните в Visual С++ команду File >- New и перейдите в окне Newна вкладку Files, добавьте в проект новый файлCData.hи включите в него приведенный выше фрагмент кода. Кроме того, необходимо включить в заголовочный файл документа ссылку на новый файл (чтобы документ знал о существовании класса CData) и создать объект класса CDataсименем DataObject: |
||
Последнее изменение этой страницы: 2018-04-12; просмотров: 352. stydopedya.ru не претендует на авторское право материалов, которые вылажены, но предоставляет бесплатный доступ к ним. В случае нарушения авторского права или персональных данных напишите сюда... |