Студопедия КАТЕГОРИИ: АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция |
SerializerDoc.h : интерфейс класса CSerlalizerDoc
#include "CData.h" //атрибуты public: CData DataObject; } После этого новым объектомDataObject можно пользоваться. В своей программе мы сохраним вводимые пользователем символы, как это делалось в предыдущем примеpe. Для этого необходимо добавить в методOnChar() вида следующий фрагмент, который заносит вводимые символы во внутренний объект DataObject(), пользуясь методом Addtext(): void CSerializerView: :OnChar(UINT nChar, UINT nRepCnt, HINT nFlags) { //TODO: добавьте код обработки сообщения // и/или вызовите обработчик по умолчанию CSerializerDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); pDoc->DataObject.AddText(CString(nChar)); Invalidate(); CView::OnChar(nChar, nRepCnt, nFlags); } По аналогии с предыдущим примером содержимое DataObjectвыводится методом DrawТехt()в методеOnDraw() вида: void CSerializerView::OnDraw(CDC* pDC) { CSerializerDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc): pDoc->DataObj ect.DrawText(pDC); } Пока новая программа ничем не отличается от предыдущей — она точно так же выводит набираемый пользователем текст. Тем не менее, когда дело доходит до сериализации, возникает проблема — мы уже не можем воспользоваться следующим кодом: void CSerializerDoc::Serialize(CArchive& ar) { if (ar.IsStoring()) { ar <<DataObject; // He получится } else { ar >> DataObject; // He получится } } Все дело в том, что мы еще не определили способ выполнения сериализации для класса CData. При попытке откомпилировать такой код Visual C++ сообщит, чтс для объекта DataObject подобное использование операторов << и >> недопустимо. Нам придется самостоятельно запрограммировать процесс сериализации и включить соответствующий код в класс CData, чтобы обеспечить возможность сериализации объектов этого класса. Поддержка сериализации в классе Прежде всего, необходимо убедиться в том, что наш класс является производным от класса MFC CObject (данный класс лежит в основе всей иерархии классов MFC): class CData: public CObject { private: CString data; . public: CData(){data = CStringC'");} void AddText(CString text){data += text;} void DrawText(CDC* pDC){pDC->TextOut(0, 0, data);} }; . Затем надо включить в определение класса макрос Visual C++ DECLARE_SERIAL, объявляющий методы, используемые в процессе сериализации: class CData : public CObject { private: CString data; DECLARE_SERIAL(CData); public: CData(){data = CStringC'");} void AddText(CString text){data += text;} void DrawText(CDC* pDC){pDC->TextOut(0, 0, data);} }; Наконец, следует переопределить метод класса CObject: class CData : public CObject { private: CString data; DECLARE_SERIAL(CData); public: CData(){data = CStringC'");} void AddText(CString text){data += text;} void DrawText(CDC* pDC){pDC->TextOut(0, 0, data);} void Serialize(CArchive& archive); }; Для написания новой версии Serialize() нам придется добавить в проект новый файл, CData.cpp. Создайте его и определите в нем метод Serialize(): #include "stdafx.h" #include "serializerDoc.h" void CData::Serialize(CArchive& archive) { } Начнем с вызова метода Serialize()базового класса (то есть класса CObject): #include "stdafx.h" #include "serializerDoc.h" void CData::Serialize(CArchive& archive) { CObject::Serialize(archive); } Далее запрограммируем сериализацию внутреннего объекта класса CString, пользуясь операторами >> и <<: #include "stdafx.h" #include "serializerDoc.h" void CData::Serialize(CArchive& archive) { CObject::Serialize(archive);
} if(archive.IsStoring()){ archive<< data; } else{ archive>>data; } } Наконец, добавим макрос IMPLEMENT_SERIAL, который содержит дополнительные методы, используемые Visual C++ для сериализации: #include "stdafx.h" #include "serializerDoc.h" void CData::Serialize(CArchive& archive) { CObject::Serialize(archive);
} if(archive.Is8toring()){ archive<< data; } else{ archive>>data; } } IMPLEMENT_SERIAL(CData,CObject, 0) Вот и все — теперь для объектов класса CDataможно выполнять сериализацию. Чтобы выполнить ее для нашего объекта DataObject, следует вызвать его методSerialize() внутриметодаSerialize()документа: void CSerializerDoc::Serialize(CArchive& ar) { DataObject.Serialize(ar); } В результате мы получили возможность сохранить объект на диске и загрузить его. Теперь вы знаете, как выполняется сериализация нестандартных объектов. Подобная методика хорошо работает в тех случаях, когда в программе есть документ и вы можете организовать сериализацию данных. Тем не менее, не каждое приложение использует документы, например программы на базе диалоговых окон обходятся без них. Давайте посмотрим, как работать с файлами при отсутствии документа. Повседневная работа с файлами На примере очередной программы мы узнаем, как выполняются стандартные Файловые операции в Visual C++. Возьмем строку "Учимся работать с файлами" и выведем ее в текстовом поле программы на базе диалогового окна. Когда пользователь нажимает кнопку Прочесть и записать файл, программа записывает строку в файлdata.dat, затем считывает ее из файла и выводит во втором текстовом поле. Создайте с помощью AppWizard программу на базе диалогового окна и присвойте ей имя filer. Деление файла на записи Чтобы наша работа с файлами была менее тривиальной, мы сохраним строку "Учимся работать с файлами" в массиве OutStrlng[]в виде четырех строк, каждая из которых состоит из 20 символов: OutString[0] ="Учимся " ; OutString[1] ="работать "; OutString[2] = "с " ; OutString[3] = "файлами " ; Каждая строка будет интерпретироваться как самостоятельная запись, или информационный объект, и отдельно заноситься в файл. В общем случае файл рассматривается как хранилище записей, каждая из которых может содержать произвольные данные. В любой момент вы можете о6ратиться к любой записи файла. При желании можно обойтись без разбивки файла на отдельные записи и занести в него любые дайные, однако группировка данных в записях облегчает доступ к ним. Кроме того, мы узнаем, как пользоваться файловым указателемдля перемещения по файлу. Указатель содержит положение текущей позиции в файле (эта Методика называется произвольным доступомпоскольку вы можете обратиться к произвольной записи). Когда придет время снова читать записи из файла, мы сохраним их в 20-символьном массиве InString[]: // filerDlg.h: заголовочный файл protected: HICON m_hIcon; char OutString[4][20]; char InString[20]; } Место для хранения данных выделено. Дальше действуем так: сначала мы записываем каждый из четырех символьных массивов (записей) в файл data.dat. Затем, при считывании данных из файла, мы рассмотрим приемы работы с файловым указателем и узнаем, как перейти к началу записи в файле data.dat для ее последующего считывания. В сущности, разбиение строки на записи бьшо предпринято именно для того, чтобы на их примере освоить приемы работы с файловым указателем. Следующим шагом нашей программы должна стать инициализация символьных массивов. |
||
Последнее изменение этой страницы: 2018-04-12; просмотров: 333. stydopedya.ru не претендует на авторское право материалов, которые вылажены, но предоставляет бесплатный доступ к ним. В случае нарушения авторского права или персональных данных напишите сюда... |