Solved

saving objects

Posted on 2004-04-14
8
327 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
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

Suggested Solutions

Errors will happen. It is a fact of life for the programmer. How and when errors are detected have a great impact on quality and cost of a product. It is better to detect errors at compile time, when possible and practical. Errors that make their wa…
Introduction This article is a continuation of the C/C++ Visual Studio Express debugger series. Part 1 provided a quick start guide in using the debugger. Part 2 focused on additional topics in breakpoints. As your assignments become a little more …
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

910 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

25 Experts available now in Live!

Get 1:1 Help Now