Solved

writing an object to a file

Posted on 2000-03-21
7
174 Views
Last Modified: 2012-05-04
I have an polymorphic object.  I'm trying to allow the user of my program to save the object for future use.

The base class of the object has a bunch of subclasses and some virtual methods.  The derived classes have subclasses.  I want to save the instances of the derived classes that the user creates by using the program.  How would i go about doing this?  The filestream methods dont seem to be working properly.
0
Comment
Question by:andrew161
  • 5
7 Comments
 
LVL 5

Expert Comment

by:Jan Louwerens
Comment Utility
What you describe is called object serialization. I know this doesn't answer your question, but it might help you to narrow down your search for more info.
0
 
LVL 22

Accepted Solution

by:
nietod earned 250 total points
Comment Utility
This is not hard to do if you will always be writting out and reading in the the same type object.  (there are cases where this is not true, where you will write objects of a certain type OR of types derived from that type.  If this is the case you have, let me know.  it is a little more complex.)

There are lots of ways to handle this, but one of the the best ways to handle it is to write input and ouput functions for all the classes involved.

Example follows.
0
 
LVL 5

Expert Comment

by:pitonyak
Comment Utility

There are many ways to do this.... One common method is as follows:

For every class, define virtual functions called read_data and write_data.

Assume something like this...

class BaseClass {
public:
   ostream& write_data(ostream& os) const;
   istream& read_data(istream& is);

protected:
};

ostream& BaseClass::write_data(ostream& os) const
{
    // stream all of the data from this class to the ostream.
   return os;
}

istream& BaseClass::read_data(istream& is)
{
    // stream all of the data from this class from the istream.
   return is;
}

class D : public BaseClass {
public:
   ostream& write_data(ostream& os) const;
   istream& read_data(istream& is);

protected:
   BaseClass object_;
   int x_;
};

ostream& D::write_data(ostream& os) const
{
    // stream all of the data from this class to the ostream.
    // remember that I have not run this code to work out the bugs.
   BaseClass::write_data(os);
   object_.write_data(os);
   os << x_ << endl;
   return os;
}

istream& D::read_data(istream& is)
{
    // stream all of the data from this class from the istream.
    // remember that I have not run this code to work out the bugs.
   BaseClass::read_data(os);
   object_.read_data(os);
   os >> x_; // remember to eat the endl... verify the best way to do this.
   return is;
}


This, of course, assumes that you know exactly what you have written and
in what order. You may have to do things in a more complicated manner including type indentifiers and then have a class builder...

Andy
0
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 22

Expert Comment

by:nietod
Comment Utility
Int the following example, the base class and the derived classes both defien input() and output() functions that allow the classes to be read and written.  The derived classes uses the base class version of the procedures to help it do it s work.

class Base
{
   int BX;
   double BD;
public:
   // output function
   void Output(ostream &Out)
   {
      Out << ' ' << BX << '  ' << BD; // Write the data members.
   };
   // Input function.
   void Input(istream &In)
   {
      In >> BX >> BD; // Read data members.
   };
};

class Derived : public Base
{
   int DX;
   double DD;
public:
   // output function
   void Output(ostream &Out)
   {
      Base::Output(Out); // write the base class
      Out << ' ' << DX << '  ' << DD; // Write the data members.
   };
   // Input function.
   void Input(istream &In)
   {
      Base::Input(Int); // Read the base class
      In >> BX >> BD; // Read data members.
   };
};

continues
0
 
LVL 22

Expert Comment

by:nietod
Comment Utility
Now both the classes had simple (built-in) data types as members, if a class has another class as a data member, you can use that class's input() and output() member functions to help you, like

class Complex
{
   int CX;
   Derived D;
public:
   // Output function
   void Output(ostream &Out)
   {
      Out << ' ' << CX; // Write the built-in data members.
      D.Output(Out); // Write the class data member.
   };
   // Input function.
   void Input(istream &In)
   {
      In >> CX >> BD; // Read the built-in data members.
      D.Output(In); // Read in the class data member.
   };
};
0
 
LVL 22

Expert Comment

by:nietod
Comment Utility
Now if a class has a pointer data member, you don't want to write out the pointer, instead you want to the data that the pointer points to.  When you read n the data, you want to allocate an object for the pointer to point to  (if it doesn't already point to something) and then read the data into the object that it points to.  Things get more complex if the data point to is an array and the size of the array can varry.  For this case you can write out a size for the array and then write out the data in the array.  When you read the array, you read the size and then allocate a new array of that size.

class Array
{
   int ItemCount; // Number of items in the array
   Derived *ArrayPtr; // -> to the array of items stored.
public:
   // Output function
   void Output(ostream &Out)
   {
      Out << ' ' << ItemCount; // Write the number of items.
      for (int i = 0;  i < ItemCount; ++i)
          ArrayPtr[i].Output(Out); // Write the an oject form the array.
   };
   // Input function.
   void Input(istream &In)
   {
      delete [] ArrayPtr; // Delete the old array.

      In >> ItemCount; // Read the number of items.
      ArrayPtr = new Derived[ItemCount]; // Allocate the items.
      for (int i = 0;  i < ItemCount; ++i)
         ArrayPtr[i].Input(In); // Read an object from the array.
   };
}
0
 
LVL 22

Expert Comment

by:nietod
Comment Utility
Let me know if you have any questions.
0

Featured Post

What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

Join & Write a Comment

Written by John Humphreys C++ Threading and the POSIX Library This article will cover the basic information that you need to know in order to make use of the POSIX threading library available for C and C++ on UNIX and most Linux systems.   [s…
This article will show you some of the more useful Standard Template Library (STL) algorithms through the use of working examples.  You will learn about how these algorithms fit into the STL architecture, how they work with STL containers, and why t…
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

772 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now