📄 ch13.htm
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html;CHARSET=iso-8859-1">
<SCRIPT LANGUAGE="JavaScript">
<!--
function popUp(pPage) {
var fullURL = document.location;
var textURL = fullURL.toString();
var URLlen = textURL.length;
var lenMinusPage = textURL.lastIndexOf("/");
lenMinusPage += 1;
var fullPath = textURL.substring(0,lenMinusPage);
popUpWin = window.open('','popWin','resizable=yes,scrollbars=no,width=525,height=394');
figDoc= popUpWin.document;
zhtm= '<HTML><HEAD><TITLE>' + pPage + '</TITLE>';
zhtm += '</head>';
zhtm += '<BODY bgcolor="#FFFFFF">';
zhtm += '<IMG SRC="' + fullPath + pPage + '">';
zhtm += '<P><B>' + pPage + '</B>';
zhtm += '</BODY></HTML>';
window.popUpWin.document.write(zhtm);
window.popUpWin.document.close();
// Johnny Jackson 4/28/98
}
//-->
</SCRIPT>
<!--<link rel="stylesheet" href="../../../../includes/stylesheets/ebooks.css">-->
<META NAME="GENERATOR" Content="Symantec Visual Page Mac 1.1.1">
<TITLE>Teach Yourself Visual C++ 6 in 21 Days -- Ch 13 -- Saving and Restoring Work--File Access</TITLE>
</HEAD>
<BODY TEXT="#000000" BGCOLOR="#FFFFFF">
<H1 ALIGN="CENTER"><IMG SRC="../button/sams.gif" WIDTH="171" HEIGHT="66" ALIGN="BOTTOM"
BORDER="0"><BR>
Teach Yourself Visual C++ 6 in 21 Days</H1>
<CENTER>
<P><A HREF="../ch12/ch12.htm"><IMG SRC="../button/previous.gif" WIDTH="128" HEIGHT="28"
ALIGN="BOTTOM" ALT="Previous chapter" BORDER="0"></A><A HREF="../ch14/ch14.htm"><IMG
SRC="../button/next.gif" WIDTH="128" HEIGHT="28" ALIGN="BOTTOM" ALT="Next chapter"
BORDER="0"></A><A HREF="../index.htm"><IMG SRC="../button/contents.gif" WIDTH="128"
HEIGHT="28" ALIGN="BOTTOM" ALT="Contents" BORDER="0"></A>
<HR>
</CENTER>
<H1 ALIGN="CENTER">- 13 -<BR>
Saving and Restoring Work--File Access</H1>
<H1></H1>
<UL>
<LI><A HREF="#Heading1">Serialization</A>
<UL>
<LI><A HREF="#Heading2">The CArchive and CFile Classes</A>
<LI><A HREF="#Heading3">The Serialize Function</A>
<LI><A HREF="#Heading4">Making Objects Serializable</A>
<LI><A HREF="#Heading5">Listing 13.3. Including the IMPLEMENT_SERIAL macro in the
class implementation.</A>
</UL>
<LI><A HREF="#Heading6">Implementing a Serializable Class</A>
<UL>
<LI><A HREF="#Heading7">Creating a Serialized Application</A>
<LI><A HREF="#Heading8">Creating a Serializable Class</A>
<LI><A HREF="#Heading9">Building Support in the Document Class</A>
<LI><A HREF="#Heading10">Adding Navigating and Editing Support in the View Class</A>
</UL>
<LI><A HREF="#Heading11">Summary</A>
<LI><A HREF="#Heading12">Q&A</A>
<LI><A HREF="#Heading13">Workshop</A>
<UL>
<LI><A HREF="#Heading14">Quiz</A>
</UL>
</UL>
<P>
<HR SIZE="4">
<BR>
Most applications provide the user the option of saving what has been created. The
creation can be a word-processing document, a spreadsheet, a drawing, or a set of
data records. Today, you will explore how Visual C++ provides you with the means
to implement this functionality easily. Today, you will learn</P>
<P>
<UL>
<LI>How Visual C++ uses C++ streams to save information about your application
<P>
<LI>How to store your application data in binary files
<P>
<LI>How to make your application objects serializable
<P>
<LI>How you can store variables of differing data types into a single file
</UL>
<H2><A NAME="Heading1"></A>Serialization</H2>
<P>There are two parts of serialization. When application data is stored on the system
drive in the form of a file, it is called serialization. When the application state
is restored from the file, it is called deserialization. The combination of these
two parts makes up the serialization of application objects in Visual C++.</P>
<P>
<H3><A NAME="Heading2"></A>The CArchive and CFile Classes</H3>
<P>Serialization in Visual C++ applications is accomplished through the CArchive
class. The CArchive class is designed to act as an input/output (I/O) stream for
a CFile object, as shown in Figure 13.1. It uses C++ streams to enable efficient
data flow to and from the file that is the storage of the application data. The CArchive
class cannot exist without a CFile class object to which it is attached.</P>
<P><A HREF="javascript:popUp('13fig01.gif')"><B>FIGURE 13.1.</B></A><B> </B><I>The
CArchive class stores application data in a CFile object.</I></P>
<P>The CArchive class can store data in a number of types of files, all of which
are descendants of the CFile class. By default, the AppWizard includes all the functionality
to create and open regular CFile objects for use with CArchive. If you want or need
to work with one of these other file types, you might need to add additional code
to your application to enable the use of these different file types.</P>
<P>
<H3><A NAME="Heading3"></A>The Serialize Function</H3>
<P>The CArchive class is used in the Serialize function on the document and data
objects in Visual C++ applications. When an application is reading or writing a file,
the document object's Serialize function is called, passing the CArchive object that
is used to write to or read from the file. In the Serialize function, the typical
logic to follow is to determine whether the archive is being written to or read from
by calling the CArchive IsStoring or IsLoading functions. The return value from either
of these two functions determines if your application needs to be writing to or reading
from the CArchive class's I/O stream. A typical Serialize function in the view class
looks like Listing 13.1.</P>
<P>
<H4>LISTING 13.1. A TYPICAL Serialize FUNCTION.</H4>
<PRE> 1: void CAppDoc::Serialize(CArchive& ar)
2: {
3: // Is the archive being written to?
4: if (ar.IsStoring())
5: {
6: // Yes, write my variable
7: ar << m_MyVar;
8: }
9: else
10: {
11: // No, read my variable
12: ar >> m_MyVar;
13: }
14: }</PRE>
<P>You can place a Serialize function in any classes you create so that you can call
their Serialize function from the document Serialize function. If you place your
custom objects into an object array, such as the CObArray that you used in your drawing
application for the past three days, you can call the array's Serialize function
from the document's Serialize function. The object array will, in turn, call the
Serialize function of any objects that have been stored in the array.</P>
<P>
<H3><A NAME="Heading4"></A>Making Objects Serializable</H3>
<P>When you created the CLine class on Day 10, "Creating Single Document Interface
Applications," you had to add two macros before you could save and restore your
drawings. These two macros, DECLARE_SERIAL and IMPLEMENT_SERIAL, include functionality
in your classes that are necessary for the Serialize function to work correctly.</P>
<P>
<H4>Including the DECLARE_SERIAL Macro</H4>
<P>You must include the DECLARE_SERIAL macro in your class declaration, as shown
in Listing 13.2. The DECLARE_SERIAL macro takes a single argument, the class name.
This macro automatically adds to your class some standard function and operator declarations
that are necessary for serialization to work correctly.</P>
<P>
<H4>LISTING 13.2. INCLUDING THE DECLARE_SERIAL MACRO IN THE CLASS DECLARATION.</H4>
<PRE>1: class CMyClass : public CObject
2: {
3: DECLARE_SERIAL (CMyClass)
4: public:
5: virtual void Serialize(CArchive &ar);
6: CMyClass();
7: virtual ~CMyClass();
</PRE>
<PRE>8: };</PRE>
<P>
<H4>Including the IMPLEMENT_SERIAL Macro</H4>
<P>You need to add the IMPLEMENT_SERIAL macro to the implementation of your class.
This macro needs to appear outside any other class functions because it adds the
code for the class functions that were declared with the DECLARE_SERIAL macro.</P>
<P>The IMPLEMENT_SERIAL macro takes three arguments. The first argument is the class
name, as in the DECLARE_SERIAL macro. The second argument is the name of the base
class, from which your class is inherited. The third argument is a version number
that can be used to determine whether a file is the correct version for reading into
your application. The version number, which must be a positive number, should be
incremented each time the serialization method of the class is changed in any way
that alters the data being written to or read from a file. A typical usage of the
IMPLEMENT_SERIAL macro is provided in Listing 13.3.</P>
<P>
<H3><A NAME="Heading5"></A>Listing 13.3. Including the IMPLEMENT_SERIAL macro in
the class implementation.</H3>
<PRE> 1: // MyClass.cpp: implementation of the CMyClass class.
2: //
3: //////////////////////////////////////////////////////////////////////
4:
5: #include "stdafx.h"
6: #include "MyClass.h"
7:
8: #ifdef _DEBUG
9: #undef THIS_FILE
10: static char THIS_FILE[]=__FILE__;
11: #define new DEBUG_NEW
12: #endif
13:
14: IMPLEMENT_SERIAL (CMyClass, CObject, 1)
15: //////////////////////////////////////////////////////////////////////
16: // Construction/Destruction
17: //////////////////////////////////////////////////////////////////////
18:
19: CMyClass::CMyClass()
20: {
21: }
22:
23: CMyClass::~CMyClass()
24: {
</PRE>
<PRE>25: }</PRE>
<P>
<H4>Defining the Serialize Function</H4>
<P>Along with the two macros, you need to include a Serialize function in your class.
This function should be declared as a void function with a single argument (CArchive
&ar), public access, and the virtual check box selected--producing the function
declaration in Listing 13.2. When you implement the Serialize function for your class,
you typically use the same approach as that used in the document class, shown in
Listing 13.1, where you check to determine whether the file is being written to or
read from.</P>
<P>
<H2><A NAME="Heading6"></A>Implementing a Serializable Class</H2>
<P>When you begin designing a new application, one of the first things you need to
design is how to store the data in the document class that your application will
create and operate on. If you are creating a data-oriented application that collects
sets of data from the user, much like a contact database application, how are you
going to hold that data in the application memory? What if you are building a word
processor application--how are you going to hold the document being written in the
application memory? Or a spreadsheet? Or a painting program? Or...you get the idea.</P>
<P>Once you determine how you are going to design the data structures on which your
application will operate, then you can determine how best to serialize your application
and classes. If you are going to hold all data directly in the document class, all
you need to worry about is writing the data to and reading the data from the CArchive
object in the document's Serialize function. If you are going to create your own
class to hold your application data, you need to add the serialization functionality
to your data classes so that they can save and restore themselves.</P>
<P>In the application that you are going to build today, you will create a simple,
flat-file database application that illustrates how you can combine a mixture of
data types into a single data stream in the application serialization. Your application
will display a few fields of data, some of which are variable-length strings, and
others that are integer or boolean, and will save and restore them in a single data
stream to and from the CArchive object.</P>
<P>
<H3><A NAME="Heading7"></A>Creating a Serialized Application</H3>
<P>You can create your own classes, which can also be serialized, for use in an SDI
or MDI application. In short, any application that works with any sort of data, whether
a database or a document, can be serialized. Now you will create a simple, flat-file
database application that you will serialize.</P>
<BLOCKQUOTE>
<P>
<HR>
<STRONG>NOTE:</STRONG> A flat-file database is one of the original types of databases. It
is a simple file-based database, with the records sequentially appended to the end
of the previous record. It has none of the fancy relational functionality that is
standard in most databases today. The database that you will build today is closer
to an old dBASE or Paradox database, without any indexes, than to databases such
as Access or SQL Server.
<HR>
</BLOCKQUOTE>
<H4>Creating the Application Shell</H4>
<P>To get your application started, create a new AppWizard application. Give your
application a name, such as Serialize, and click OK to start the AppWizard.</P>
<P>In the AppWizard, select to create a single document style application using the
Document/View architecture. You can choose to include support for ActiveX controls
in the third AppWizard step, although it's not really necessary for the example that
you will build.</P>
<P>In the fourth step, be sure to specify the file extension for the files that your
application will create and read. An example of a file extension that you might want
to use is ser for serialize or fdb for flat-file database.</P>
<P>In the sixth AppWizard step, you need to specify which base class to use for the
application view class. For a description of the different base classes available
for inheriting the view class from, refer to Day 10 in the section "The Document/View
Architecture." For the sample application you are building, because it will
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -