Solved

writing an object to a file

Posted on 2000-03-21
7
180 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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 250 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
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
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

Industry Leaders: 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!

Question has a verified solution.

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

Article by: SunnyDark
This article's goal is to present you with an easy to use XML wrapper for C++ and also present some interesting techniques that you might use with MS C++. The reason I built this class is to ease the pain of using XML files with C++, since there is…
This article shows you how to optimize memory allocations in C++ using placement new. Applicable especially to usecases dealing with creation of large number of objects. A brief on problem: Lets take example problem for simplicity: - I have a G…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
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.

627 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