Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

writing an object to a file

Posted on 2000-03-21
7
Medium Priority
?
183 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
ID: 2641443
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 1000 total points
ID: 2641497
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
ID: 2641507

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
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 22

Expert Comment

by:nietod
ID: 2641528
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
ID: 2641549
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
ID: 2641596
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
ID: 2641600
Let me know if you have any questions.
0

Featured Post

Vote for the Most Valuable Expert

It’s time to recognize experts that go above and beyond with helpful solutions and engagement on site. Choose from the top experts in the Hall of Fame or on the right rail of your favorite topic page. Look for the blue “Nominate” button on their profile to vote.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

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…
  Included as part of the C++ Standard Template Library (STL) is a collection of generic containers. Each of these containers serves a different purpose and has different pros and cons. It is often difficult to decide which container to use and …
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.
Suggested Courses

876 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