?
Solved

saving objects

Posted on 2004-04-14
8
Medium Priority
?
333 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
[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
  • 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
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!

 

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 2000 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

Want to be a Web Developer? Get Certified Today!

Enroll in the Certified Web Development Professional course package to learn HTML, Javascript, and PHP. Build a solid foundation to work toward your dream job!

Question has a verified solution.

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

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…
  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 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.
Suggested Courses

764 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