Студопедия

КАТЕГОРИИ:

АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция

Сериализация объекта 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; просмотров: 287.

stydopedya.ru не претендует на авторское право материалов, которые вылажены, но предоставляет бесплатный доступ к ним. В случае нарушения авторского права или персональных данных напишите сюда...