Solved

saving objects

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

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
Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

 
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

Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

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…
Many modern programming languages support the concept of a property -- a class member that combines characteristics of both a data member and a method.  These are sometimes called "smart fields" because you can add logic that is applied automaticall…
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 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.

708 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

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now