954,498 Members — Technology Publication meets Social Media
Username:
Password:
Lost login information?
Have something to say? Contribute New Article Reply to this Article

class serialization issues

class item
{
string name;
string identifier;
public:
  item( string name,string id):{this->name=name;this->identifier=id;}
        friend ostream& operator<<(ostream&, const item&);
        friend istream& operator>>(istream&, item&);
};
ostream& operator<<(ostream& out, const item& temp)
{
	out<<item.name<<" "<<item.identifier<<endl;
	return out;
}
istream& operator>>(istream& in, Cmessage& temp)
{
	getline(in,item.name);//in case sring has space char
	getline(in,item.identifier);

	return in;
}
class CGuser
{
	bool online;
	int score;
	string name;
	string password;
	string IP;
	vector<item> messages;
	vector<string> v_friends;
	vector<string> groups;
public:
        CGuser(string name, string password)	
       {	
        this->name=name;
        this->password=password;
        this->score=0;}
	friend ostream& operator<<(ostream&, const CGuser&);
	friend istream& operator>>(istream&, CGuser&);

ostream& operator<<(ostream& out, const CGuser& temp)
{
	int size;
	out<<temp.online<<endl;
	out<<temp.score<<endl;
	out<<temp.name<<endl;
	out<<temp.password<<endl;
	out<<temp.IP<<endl;

	size=temp.messages.size();
	out<<size<<" ";
	for(int i=0;i<size;i++)
		out<<temp.messages[i]<<endl;

	size=temp.v_friends.size();
	out<<size<<" ";
	for(int i=0;i<size;i++)
		out<<temp.v_friends[i]<<endl;

	size=temp.groups.size();
	out<<size<<" ";
	for(int i=0;i<size;i++)
		out<<temp.groups[i]<<endl;

	out<<endl;
	return out;
}
istream& operator>>(istream& in, CGuser& temp)
{
	int size;
	string stmp;
	Cmessage cmg;

	in>>temp.online;
	in>>temp.score;
	getline(in,temp.name);
	getline(in,temp.password);
	getline(in,temp.IP);

	in>>size;
	for(int i=0;i<size;i++)
	{
		in>>cmg;
		temp.messages.push_back(cmg);
	}

	in>>size;
	for(int i=0;i<size;i++)
	{
		getline(in,stmp);
		temp.v_friends.push_back(stmp);
	}
	
	in>>size;
	for(int i=0;i<size;i++)
	{
		getline(in,stmp);
		temp.groups.push_back(stmp);
	}
	
	return in;
}
};
CGuser *user;
string name,pass;

cout<<"enter name:"<<endl
cin>>name;
cout<<"enter password"<<endl;
cin>>pass;
user= new CGuser(name,pass,0);
cout<<user;

the problem is with the last line, and what I mean problem is than it prints a number(I suspect the address in memory where user is allocated)instead of each field of the class
Another question that I have is how do I send over the network first just the item class, then the CGuser class(both client and server are the same endianess)

CPT
Light Poster
30 posts since Aug 2010
Reputation Points: 10
Solved Threads: 1
 

you input and output operator takes a CGuser by reference.
Do following:

cout<< *user;
alwaysLearning0
Junior Poster
119 posts since Apr 2009
Reputation Points: 64
Solved Threads: 19
 

>cout<
user is a pointer, you need to dereference it first:


cout << *user;

Though bare pointers are so passé. You should prefer smart pointers unless there's good reason to do otherwise:

string name, pass;

cout << "enter name: ";
cin >> name;

cout << "enter password: ";
cin >> pass;

auto_ptr<CGuser> user(new CGuser(name,pass,0));

cout << *user;


Note: auto_ptr is used in the example because you're guaranteed to have it available. However, it's problematic in terms of ownership and has actually been deprecated in the upcoming standard. The replacement in the new standard is unique_ptr. You can also use boost::shared_ptr or tr1::shared_pointer with current compilers.

Narue
Bad Cop
Administrator
15,460 posts since Sep 2004
Reputation Points: 6,464
Solved Threads: 1,401
 

Why the pointer in the first place? You could manage without it, can't you?

firstPerson
Senior Poster
3,923 posts since Dec 2008
Reputation Points: 841
Solved Threads: 608
 

so regarding my second question about sending it over a network; the v_friends,messages and groups fields are pointers to vectors, right?(so they will have only 4 bytes each ?) wouldn't that be a problem when I allocate a buffer with the size of the class(you know, to send it)?
Why the pointer in the first place? You could manage without it, can't you?
Well I think I can, but in this case I will need a default constructor for the class

CPT
Light Poster
30 posts since Aug 2010
Reputation Points: 10
Solved Threads: 1
 
wouldn't that be a problem when I allocate a buffer with the size of the class(you know, to send it)?


You need to read up on serialization. Real serialization, not this shallow copy crap.

Narue
Bad Cop
Administrator
15,460 posts since Sep 2004
Reputation Points: 6,464
Solved Threads: 1,401
 
You need to read up on serialization. Real serialization, not this shallow copy crap.


Well, I've tried to search with google and this is what I've found so far.I'm open to better serialization methods

CPT
Light Poster
30 posts since Aug 2010
Reputation Points: 10
Solved Threads: 1
 

Well, you don't seem to understand serialization at all if the problem is serializing a pointer rather than the pointed to data. The simplest method of serialization is converting the collective value of an object into a string. For example:

#include <boost/lexical_cast.hpp>
#include <iostream>
#include <string>
#include <vector>

using namespace std;

class foo {
    string _id;
    vector<int> _data;
public:
    foo(const string& id, const vector<int>& data);
    string to_string();
    foo& from_string(const string& s);
};

foo::foo(const string& id, const vector<int>& data)
    : _id(id), _data(data)
{}

string foo::to_string()
{
    string result(_id + "[");
    
    for (vector<int>::size_type i = 0; i < _data.size(); i++) {
        result += boost::lexical_cast<string>(_data[i]);
        
        if (i < _data.size() - 1)
            result += ",";
    }
    
    return result + "]";
}

foo& foo::from_string(const string& s)
{
    // Assuming s is formatted properly for brevity
    
    string::size_type begin = s.find_first_of("[");
    string::size_type end;
    
    _id = s.substr(0, begin);
    
    while ((end = s.find_first_of(++begin, ',')) != string::npos) {
        string data_field = s.substr(begin, end - begin);
        
        _data.push_back(boost::lexical_cast<int>(data_field));
    }
    
    return *this;
}

int main()
{
    vector<int> v;
    
    v.push_back(11);
    v.push_back(22);
    v.push_back(33);
    v.push_back(44);
    
    foo f1("test", v);
    string s = f1.to_string();
    foo f2 = f1.from_string(s);
    
    cout << s << '\n' << f2.to_string() << '\n';
}
Narue
Bad Cop
Administrator
15,460 posts since Sep 2004
Reputation Points: 6,464
Solved Threads: 1,401
 

Examples of real serialization methods or libraries are:

Boost.Serialization

Google's protobuf

JSON

Serialization requires two things: a way to deconstruct an object tree into a buffer from which the tree can be reconstructed (which usually requires some form of type identification), and a way to read and write the buffer that is compact, system-agnostic and easy to parse (e.g. XML, JSON, protobuf, etc.).

mike_2000_17
Posting Virtuoso
Moderator
2,135 posts since Jul 2010
Reputation Points: 1,634
Solved Threads: 457
 

This question has already been solved

Post: Markdown Syntax: Formatting Help
You
View similar articles that have also been tagged: