Solved

saving objects

Posted on 2004-04-14
8
331 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 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

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

IntroductionThis article is the second in a three part article series on the Visual Studio 2008 Debugger.  It provides tips in setting and using breakpoints. If not familiar with this debugger, you can find a basic introduction in the EE article loc…
Basic understanding on "OO- Object Orientation" is needed for designing a logical solution to solve a problem. Basic OOAD is a prerequisite for a coder to ensure that they follow the basic design of OO. This would help developers to understand the b…
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 goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…

726 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