Solved

saving objects

Posted on 2004-04-14
8
328 Views
Last Modified: 2012-05-04
Hi,

I wish to save some objects in a data file to make the state of an application persistent.  Is this possible in c++?  As things stand I have one main object with member variables of different classes built into it.  For example, class main has a vector<Person> people; in it.  I simply wish to store main transparently in a file and recreate it with the exact state of the object and all its sub objects intact.  Am I allowed or is there some more low level facility?  I have used Java in the past and ObjectStreams, or something similar, so would like a c++ equivalent.

Thanks for any help.
0
Comment
Question by:jasoncpp
  • 5
  • 2
8 Comments
 
LVL 30

Expert Comment

by:Axter
ID: 10826481
>>Is this possible in c++?  
Yes

>>Am I allowed or is there some more low level facility?  

You can do this by creating and operator>>() and an operator<<() function for your class.

These functions would then read and write data for your class.
0
 
LVL 30

Expert Comment

by:Axter
ID: 10826516
If you're using MFC, you can use CObject with Serialize member function.

What type of application do you have, and what compiler are you using?
0
 
LVL 30

Expert Comment

by:Axter
ID: 10826712
Here's some example code for using operator>>() and operator<<()

class person
{
public:
      person(const std::string& Name, int Age)
            :m_Name(Name), m_Age(Age)
      {
      }
      person()
            :m_Age(0)
      {
      }
      friend ostream& operator<<(ostream& s, const person & src)
      {
            s << src.m_Name << "\t" << src.m_Age << "\t";
            return s;
      }
      friend istream& operator>>(istream& s, person & src)
      {
            std::getline(s, src.m_Name, '\t');
            std::string Age;
            std::getline(s, Age, '\t');
            src.m_Age = atoi(Age.c_str());
            return s;
      }
private:
      std::string m_Name;
      int m_Age;
};

int main(int argc, char* argv[])
{
      person MyPerson1("David Axter", 43);
      person MyPerson2("Bush Stinks", 23);
      person MyPerson3("(ABB) anything but bush", 11);
      cout << MyPerson1 << endl;
      cout << MyPerson2 << endl;
      cout << MyPerson3 << endl;

      fstream file;
      file.open("c:\\testx.txt", ios_base::out);
      file << MyPerson1;
      file << MyPerson2;
      file << MyPerson3;
      file.close();

      cout << endl << endl << endl;
      file.open("c:\\testx.txt", ios_base::in);
      person MyPerson_Copy[3];
      for (int i = 0;i < 3;++i)
      {
            file >> MyPerson_Copy[i];
            cout << MyPerson_Copy[i] << endl;
      }

      system("pause");
      return 0;
}

0
Courses: Start Training Online With Pros, Today

Brush up on the basics or master the advanced techniques required to earn essential industry certifications, with Courses. Enroll in a course and start learning today. Training topics range from Android App Dev to the Xen Virtualization Platform.

 

Author Comment

by:jasoncpp
ID: 10826917
Didn't realise I would have to overload the << and >> operators, least I know now, thanks.  The main object isnt an mfc one, I am using mfc.  Could the mfc serialize make my task easier for non-mfc objects or must I serialize every class as explained?

I'm using VC++ 6.

Secondly, can you give me a quick code example of Person having another custom class as its attribute, for example, Car or anythign else please?  I just want to clarify how compound objects get saved using << >>.  

Cheers.
0
 
LVL 4

Expert Comment

by:bkfirebird
ID: 10826981
like Axter said, you can derive any class from CObject and make it serializable
0
 
LVL 30

Accepted Solution

by:
Axter earned 500 total points
ID: 10827120
>>Could the mfc serialize make my task easier for non-mfc objects or must I serialize every class as explained?
Any class that you serialize would have to be derived from CObject, so unless you use a secondary wrapper class, you can't CObject::Serialize function with non-mfc objects.

>>Secondly, can you give me a quick code example of Person having another custom class as its attribute
Sure.
Check out the following example, and I hope you don't mind the political satire mixed in. :-)

class IQLevel
{
public:
      enum Level{Dummy, Normal, Smart};
      IQLevel(Level level, int level2):m_level(level), m_level2(level2){}
      IQLevel():m_level(Dummy), m_level2(0){}
      friend ostream& operator<<(ostream& s, const IQLevel & src)
      {
            s << src.m_level << "\t" << src.m_level2 << "\t";
            return s;
      }
      friend istream& operator>>(istream& s, IQLevel & src)
      {
            std::string data;
            std::getline(s, data, '\t');
            src.m_level = (Level)atoi(data.c_str());
            std::getline(s, data, '\t');
            src.m_level2 = atoi(data.c_str());
            return s;
      }
private:
      Level m_level;
      int m_level2;
};

class person
{
public:
      person(const std::string& Name, int Age, IQLevel &iqlevel)
            :m_Name(Name), m_Age(Age), m_IQLevel(iqlevel)
      {
      }
      person()
            :m_Age(0)
      {
      }
      friend ostream& operator<<(ostream& s, const person & src)
      {
            s << src.m_Name << "\t" << src.m_Age << "\t" << src.m_IQLevel;
            return s;
      }
      friend istream& operator>>(istream& s, person & src)
      {
            std::getline(s, src.m_Name, '\t');
            std::string Age;
            std::getline(s, Age, '\t');
            src.m_Age = atoi(Age.c_str());
            s >> src.m_IQLevel;
            return s;
      }
private:
      std::string m_Name;
      int m_Age;
      IQLevel m_IQLevel;
};

int main(int argc, char* argv[])
{
      person MyPerson1("David Axter", 43, IQLevel(IQLevel::Smart, 160));
      person MyPerson2("Bush Stinks", 23, IQLevel(IQLevel::Dummy, 22));
      person MyPerson3("(ABB) anything but bush", 11, IQLevel(IQLevel::Normal, 110));
      cout << MyPerson1 << endl;
      cout << MyPerson2 << endl;
      cout << MyPerson3 << endl;

      fstream file;
      file.open("c:\\testx.txt", ios_base::out);
      file << MyPerson1;
      file << MyPerson2;
      file << MyPerson3;
      file.close();

      cout << endl << endl << endl;
      file.open("c:\\testx.txt", ios_base::in);
      person MyPerson_Copy[3];
      for (int i = 0;i < 3;++i)
      {
            file >> MyPerson_Copy[i];
            cout << MyPerson_Copy[i] << endl;
      }

      system("pause");
      return 0;
}

0
 
LVL 30

Expert Comment

by:Axter
ID: 10827185
When using stream to save and retrieve objects, a key thing to keep in my is that you need to use a character that will seprate the objects.
What ever character you use for object seperation, can not be a character that could possibly be part of the object.
Example, you can't use a space for the object sperator, because Name object would have a space in it for First and Last name.

Also, you usually want each complex object resposible for it's own read/write stream operations.

As you can see with the example code, the nice thing about this method, is that it lets you use the code for sending the data to a file, and for sending it to the screen.
0
 

Author Comment

by:jasoncpp
ID: 10827313
Great stuff and amusing too!  You have been very helpful.  Thanks :)
0

Featured Post

Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

Question has a verified solution.

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

Suggested Solutions

Unlike C#, C++ doesn't have native support for sealing classes (so they cannot be sub-classed). At the cost of a virtual base class pointer it is possible to implement a pseudo sealing mechanism The trick is to virtually inherit from a base class…
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…
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.

806 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