Add a file storage and loading function for the C ++ Program

Source: Internet
Author: User

I. Introduction

Why is it a waste of time to design an algorithm to implement data file storage and debugging code? The Boost library can do these tasks for you. With the help of serialized templates, you can easily store data in your own custom format files. This article will teach you how to easily store and read back data.

  Ii. Overview

When developing a software package, you always want to focus on the features of the software. What worries you most is that it takes a lot of time to write code, and the code may be applied to a large number of other programs. That's exactly what reuse means. You may want someone else to write such ready-made code for you.

A good example of this type of problem is the ability to archive your program. For example, you may be writing the greatest astronomical Program-in which your users can easily enter time and coordinates, and your program is responsible for drawing the map of the current sky. However, if you give your users the ability to highlight certain stars, they can easily highlight on the map. Finally, you allow users to save their configurations for future use.

Your programs focus on astronomy programming. You are not writing a general library to save documents, so you don't have to spend a lot of time on storage functions, because you need to focus on the astronomical features of the program. If you are using C ++ programming, You can get help from the Boost reuse library. To save files, the Boost library includes a serialized class, which is exactly what you need.

If you have successfully created your program project, you may have a class that contains user information or documents. For example, you may have a class that lists the names and locations of users' favorite stars. (Please forgive the simplification here ). This is the data you want the user to save to the disk. After all, almost all programs have the file storage function. Microsoft Word stores text and formatted data, while Excel stores work order data. An excellent map program allows users to save their favorite locations, GPS routes, journeys, and so on.

With the help of Boost serialized libraries, it is easy to save-all you have to do is set your classes, and the libraries are responsible for everything else-so that you can focus on the real work.

The idea is simple: you have created an object that contains user data. When you are preparing to Save the information, SELECT File | Save As and select a File name from the File dialog box. With Boost, your program will save the data to the selected file. Later, when the user restarts the program, SELECT File | Open, select the saved File, and your program uses Boost again-but re-loads the data this time. Therefore, this object is re-generated. Look, user data has been replied! Or, from the user's point of view, the document has been opened.

The following example shows how to save and load some graphics classes. The first class, Vertex, describes a two-dimensional Vertex. The second class, Polygon, contains a Vertex instance container. The third class, Drawing, contains a Polygon container.

It is undoubtedly a nightmare to save all of this to a document-this is not a time-consuming place-you need to implement the best graphic programming, because this is your expertise. Well, let the Boost library do everything else for you.

  Iii. serializing a class

First, consider the Vertex class. This class is the easiest to serialize because it does not contain other objects. This class contains two values, x and y, and both are double type. I also defined several functions for this class to access x and y, as well as a dump function, which is used to deliver the values of x and y to the console. Finally, I have two constructors, one being the default and the other being used as the input parameter. (For the sake of simplicity, this routine has not made any actual drawing. Sorry !)

The most attractive part below is the required code line to serialize this class. The following is the class (note the bold part ):

Class Vertex {
Private:
Friend class boost: serialization: access;
Template
Void serialize (Archive & ar, const unsigned int version)
{
Ar & x;
Ar & y;
}
Double x;
Double y;
Public:
Vertex () {}// a default constructor is required for serialization
Vertex (double newX, double newY): x (newX), y (newY ){}
Double getX () const {return x ;}
Double getY () const {return y ;}
Void dump (){
Cout <x <"" <y <endl;
}
};

Note that at the end of the program, I did not actually use the default constructor Vertex (), but the serialization library actually called it, so I need to include it.

The serialization part first serializes the inventory to take private members, especially the subsequent serialization functions. Robert Ramey, creator of the serialization library, points out that you do not need any functions, including those in the derived classes, to call your serialization method. You only need to call the serialization library. Therefore, to protect your class, you need to declare the serialization function as private, and then allow restricted access to the serialized library. This is done by setting the class boost: serialization :: the access statement is implemented for your class's friends. See the code.

Next, it is a serialized function, which is a template function. If you are not familiar with the template, It Doesn't Matter: You don't need to understand the template, but you can still make it work. However, make sure that you understand the core of the serialization function:

ar & x;
ar & y;

First, let me declare that the two lines of code do not declare reference variables, although the form looks similar. Instead, they call an & operator and write your class members to a file or read them in. Yes, you have recognized it correctly; this function achieves the effect of one stone and two birds (or, more accurately, using a set of code to complete two tasks. When you save a Vertex object to a file, the serialization library calls this serialization function. The first line writes the value of x to the file, the second line writes the value of y to the file. Later, when you read a Vertex object from a file, the first row reads the x value from the file, and the second row reads the y value from the file.

This is a special operator overload! In fact, & characters are an operator defined inside the serialized library. Fortunately, you don't need to understand how it works.

Well, it's that simple. The following is some sample code. You can try to save a Vertex object to a file:

Vertex v1(1.5, 2.5);
std::ofstream ofs("myfile.vtx");
boost::archive::text_oarchive oa(ofs);
oa << v1;
ofs.close();

That's it! The first line generates a Vertex object. Open a file in the following four lines, combine a specific serialization class with the file, write it to the file, and close the file. The following code reads a Vertex object from a file:

Vertex v2;
std::ifstream ifs("myfile.vtx", std::ios::binary);
boost::archive::text_iarchive ia(ifs);
ia >>v2;
ifs.close();
v2.dump();

This code generates a Vertex instance and then opens a file (this time for the purpose of reading), associates a serialized class with the file, and reads the object, close the file. Finally, the Code outputs the Vertex value. If you put the preceding two program segments in a main function and run them, you will see two original values: 1.5 and 2.5.

Note:

Note that the file extension I use is. vtx. This is not a special extension; it is a custom extension. This sounds silly and trivial, but we are actually creating our own file format. To point out this special file format, I used the extension named. vtx, which means Vertex.

Iv. serialized containers

In my example, a drawing object can contain multiple polygon objects (I store them in a vector and this vector is a member of the standard library container template ), each polygon object can contain multiple Vertex objects (I also store them using vectors ).

The serialized Library provides the ability to save arrays and containers. Because you can store pointers in arrays, The serialized Library also supports pointers. Consider: if you have an array containing the Vertex pointer and you write the array directly into a file, you will have a bunch of pointers stored in the file, instead of the actual Vertex data. The pointers are only numbers (memory locations), which are meaningless when data is read back later. Therefore, the database cleverly captures data from objects rather than pointers.

Considering that storage is the container object, you need to serialize each class. In the serialization method, you can read and write data to the container, just as you operate on another member. Your container can be an array of memory in a simple language (such as Vertex * vertices [10];) or a container from a standard library. Because it is the 21st century, I like to keep up with the pace of the times, so I chose to use the standard library in this example.

Although you can write code in your serialized class for containers and every member, you do not have. As a substitute, the Library is already very intelligent to automatically traverse containers. All you need to do is write the container, as shown below, where vertices is a container:

ar & vertices;
Let the database do the rest of the work. Believe it? The following is the Polygon-like code. The serialized part is marked in bold:

class Polygon {
 private:
  vector vertices;
  friend class boost::serialization::access;
  template
  void serialize(Archive & ar, const unsigned int version)
  {
   ar & vertices;
  }
 public:
  void addVertex(Vertex *v) {
   vertices.push_back(v);
  }
  void dump() {
   for_each(vertices.begin(), vertices.end(), mem_fun(&Vertex::dump));
  }
};

First, note that I use a vector to store the layout. (If you are a newbie to the template, it doesn't matter, just put the vector Just store the vector pointing to the Vertex instance, because it is actually like this .). Next, in a serialized function, I don't want to traverse this vector-write every member. On the contrary, I just want to read and write the whole vector:

ar & vertices;
The establishment of two common methods can be used to conveniently operate the polygon. The first addVertex method allows you to add another node to the polygon. It uses the push_back method, which is a standard method for adding a vector. The Dump function traverses this vector and writes each vector to the standard output device.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.