22858 total geeks with 3297 solutions
Recent challengers:
best bread maker
 Welcome, you are an anonymous user! [register] [login] Get a yourname@osix.net email address 

Articles

GEEK

User's box
Username:
Password:

Forgot password?
New account

Shoutbox
sefo
anilg, new comments are deleted automaticall y because of some abuse recently
anilg
this is plain wierd. I submitted comments twice to article 950, and they dont seem to be there. Something wrong with the comment code?
CodeX
shout-boxes in general are old + the staff thing happened to everyone after an issue 2 months ago
anilg
/me is no longer staff :(
anilg
Also, osix's shoutbox predated twitter. Heh.

Donate
Donate and help us fund new challenges
Donate!
Due Date: Jul 31
July Goal: $40.00
Gross: $0.00
Net Balance: $0.00
Left to go: $40.00
Contributors


News Feeds
The Register
UK.gov sticks to IE
6 cos it"s more
"cost effective",
innit
T-Mobile UK pumps
out the iPhone 4
Polaroid 300
instant print
camera
NatWest dumps O2
Money
YouTube ups video
time limit
Alleged expenses
fiddlers to face
justice
Nude trampolinist
bounces free from
court
Nexus One phone
rockets to 28,000ft
UK.gov drops £6m on
Google
Fake Firefox update
used to sling
scareware
Slashdot
British ISPs Favour
Well-Connected
Customers
"Bizarre"
Nanobubbles Found
In Strained
Graphene
1-in-1,000 Chance
of Asteroid Impact
In
...
2182?
2 Chinese ISPs
Serve 20% of World
Broadband Users
World"s Fastest
Hybrid OK"d For
Production
Sometimes It"s OK
To Steal My Games
Thermoelectrics
Could Let You Feel
the Heat In Games
KDE SC 4.7 May Use
OpenGL 3 For
Compositing
Perl 6, Early, With
Rakudo Star
Internal Costs Per
Gigabyte —
What Do You Pay?
Article viewer

Serialization in C++



Written by:dimport
Published by:CodeX
Published on:2003-06-21 07:19:46
Topic:C++
Search OSI about C++.More articles by dimport.
 viewed 44574 times send this article printer friendly

Digg this!
    Rate this article :
What is serialization, you might be wondering? Serialization is simple, it is basically converting a class into binary form so that it can be read later on or sent over a network and then read out of the file or over the network as an object. It is a simple yet powerful concept, and allows an object to retain its form even across a network.

Basically if I have a class called Test() and its constructor takes a string argument, then if I set its string value to "Hello", and I want to transmit it over a network or store it in a file to be read later, then I can use serialization to convert it into binary form. This way when the file is read later or the network transmission is received the user can read the string value of the original object. Sound a little confusing? This next example should shed some light on what exactly I'm talking about:

//Attempt at Simple Object Serialization in C++
//By: Eric Scrivner (a.k.a bitshift)
//bitshift2002@yahoo.com
#include <iostream> //iostream
#include <fstream> //fstream
#include <string> //string
using namespace std;
 class Test {
private:
    int value;
public:
    Test(int val) : value(val) { }
    Test() { value = 0; }
     int getValue() { return value; }
     ~Test() { value = 0; }
     Test operator=(int val) {
        if(value == val)
            return *this;
         value = val;
         return *this;
    }
    Test operator=(Test val) {
        if(value == val.value)
            return *this;
         value = val.value;
         return *this;
    }
};

int main(int argc, char** argv) {
    cout<<"*Creating Test Object..."<<endl;
     Test write(123);
    cout<<"t-Object has value "<< write.getValue() <<endl;
    cout<<"*Attempting to Serialize Object..."<<endl;
     ofstream out("binary.txt", ios::binary);
    out.write((char*)&write, sizeof(write));
     cout<<"*Closing File Stream...n"<<endl;
    out.close();
     cout<<"*Attempting to Read Object From File..."<<endl;
    Test read(1);
    ifstream in("binary.txt", ios::binary);
     in.read((char*)&read, sizeof(read));
    cout<<"t-Object has value "<< read.getValue() <<endl;
    return 0;
}


Basically in this example we created a simple working class called Test that stores an integer value, simple right? We then created a test object and then saved it to a file in binary form. We closed the file output stream and then opened a binary input stream, from which we then read the binary data out into a new class of type Test. After running the program once, try commenting out the file writing part and seeing if it still works.

Unsurprisingly it still does.

[b] Conclusion [b]

This article has hopefully attempted its goal of showing you how to perform simple object serialization. I hope that I have shed some light on this extremely valuable topic. Serialization is a powerful concept, and unlike Java it does not come standard in C++, so it takes a little more work. I hope that you have found the source code simple, and as a word of advice don't use this form of opening files to perform serialization:

ofstream out;
out.open("binary.txt", ios::binary);
out.write((char*)object, sizeof(object));
out.close();


Though this looks perfectly valid, for some reason it does not work with most compilers(i.e g++, MingW32, & Visual C++). In Visual C++ it even causes an assertion failure error. I haven't yet found why this doesn't work, but it causes many extremely frustrating bugs.

This article was originally written by bitshift

Did you like this article? There are hundreds more.

Comments:
Anonymous
2006-01-25 14:59:40
i need this topic more elaboratedly
Anonymous
2006-05-29 21:07:01
Need serialization in C++? http://s11n.net
xpi0t0s
2006-06-01 05:23:30
A text file isn't a good choice; if it is ftp'd between systems there's a risk of corruption due to CR/LF onversion which would completely trash the file.

Casting object instead of &object to a char* doesn't work because object is not a pointer but &object is. Remember: C++ Is Not Java!! Java has no pointers (actually, everything is a pointer), but C++ distinguishes between pointer and non-pointer variables.

The cast doesn't throw a compiler error because C++ assumes you know what you are doing and it is perfectly possible to cast an int with value 123 to a char pointer, but don't forget when you attempt to dereference that pointer (by calling out.write() for example) it will be now pointing at 0x0000007b which will almost certainly not work.
xpi0t0s
2006-06-01 05:50:41
Anonymous(1): what more do you want to know about object serialisation? This seems to cover it and the program should work regardless of what data is in class Test.
Anonymous
2007-02-20 20:41:39
This does NOT handle the problem of Endian - It will only work on systems with the same endian byte order.

In most cases, it is fine, but not all.
Anonymous
2007-04-03 17:34:09
As mentioned by others, this is not going to handle well on all systems. Furthermore, you cannot use this methods with more complex types (if you had a string within your class, for example) because they often contain pointers. The best route for class serialization is writing your own serializers for each datatype and then writing a(n) (un)serialize method for your class specifically.
Anonymous
2007-06-12 13:04:59
This is a pretty poor solution unless you are using the same compiler (and relevant compiler options) and processor at either end of the 'link' and are only serialising simple objects. As mentioned above, it is generally better to write your own serialize() methods.
Anonymous
2007-08-06 04:19:52
It doesn't work when some members of the class are pointers.
Anonymous
2007-12-31 19:55:54
The way to go is to overload the global operators >> and << for your object with the first argument being a C++ stream and the second your object type and then serialize all relevant data members.

Your method is NOT guaranteed to work with different compilers, different versions of the same compiler, the same version of the compiler with different memory alignment settings, or different processor architectures. As others have mentioned, pointers (and references) are a huge problem.

There is also a HUGE security problem since depending on your compiler, you may also read the object's vtable from the stream, which is extremely dangerous since a manipulated file/network stream can be used to call arbitrary code on your system.

And if you add a data member to an object in a new version of your software, all your existing files/streams will become unreadable.

Your're also serializing any cached state information of the object, which may become invalid in the new context. For example, if you store something like the number of processors on the system in a member variable, this is what happens: When the object is read in on a different system, the object also reads in the number of processors and thus uses the no longer appropriate info that was in the file, and you get undefined behavior once the object accesses that variable.

Static data members may become an issue as well.
Anonymous
2008-10-02 07:24:00
poda pulle
Anonymous
2009-04-22 09:03:31
This is not going to handle well on all systems. Furthermore, you cannot use this methods with more complex types because they often contain pointers. The best route for class serialization is writing your own serializers for each datatype and then writing a(n) (un)serialize method for your class specifically. online games
Anonymous
2009-07-16 13:17:00
penis
Anonymous
2009-08-20 15:49:40
This code is so wrong on so many levels. As an example, think of a class with virtual functions and try deserializing it using the above technique. The classes with virtual functions define an extra pointer at the beginning on the class definition which points to a virtual table translating the calls to a virtual function to its concrete implementation. The above serialization will keep the pointer to vtbl in a stream. Object graphs, i.e. complex relationships between objects, will not be serialized properly as well. So the only scenario that is going to work is when the class does not have virtual functions and has no pointers to other instances. If you really want to serialize class hierarchies, consider using Db4o API.
Anonymous
2009-12-03 03:11:09
This will only store the address of the object in the file... as soon as your program terminates that address will stop pointing at the object and will only give you garbage if you try to initialize a new object from what is in there... the only reason it works is because while the program is still running the address points to the same object... you are not even creating a new object. If you were to change the 1st object the 2nd object would be modified as well because the memory that they are pointing at is the same.
Anonymous
2009-12-23 18:52:44
You may encode the stream into something that doesn't contain control chars. Hexadecimal, base64 (more compact) etc. encoding will do it, but bear in mind that you can't ignore structure padding, endianness, alignment and width/precision. I think too, that you must write a serialization specialization (meta class) for each type, since C/C++ is not Java.
If you don't handle those issues, you'll cause a mess when a remote end uses another compilation and/or platform.
So, be careful with your RTTI, you shouldn't declare long and int etc. because these types can vary in size on another platform. Therefore, be as specific as possible and embed types like uint32_t. I'd go as far as doing the same with float types, like float32, float64, float80 etc...
If you do all that, you can also handle member size and alignment problems. But even then, be aware of the whole struct alignment, it can be higher as several stuct members require, for example when aligned 128bit and wider loads occur (SSE etc.).
This means, you must create proper instances and copy the extracted/converted member fields in them regarding the local meta class; you MUSTN'T simply cast any pointer coming along in a buffer or sth.
You see, there is much to take care of, eventually more than i've prosed so far :-)
=> the preprocessor, sizeof, offsetof and alignof will be dear friends :-)
=> boost or C++0x tuple templates can be a real benefit because of iteration capabilities (what structs/classes lack of)
Anonymous
2010-01-20 00:50:00
http://www.bagscabin.com/mulberry bags
Anonymous
2010-01-30 03:40:42
Thanks guy! I thought Serialization mechanism is a solely feature of some advanced programming framework. Nice!
Anonymously add a comment: (or register here)
(registration is really fast and we send you no spam)
BB Code is enabled.
Captcha Number:


Blogs: (People who have posted blogs on this subject..)
harry
Blog entry for Thu 28th Sep 12pm on Thu 28th Sep 12pm
Hi In school i want to net send my mates but hide who its coming off any ideas. no programs though as the machine in school sets off an alarm if it detects any batch files etc... thanks Harry


     
Your Ad Here
 
Copyright Open Source Institute, 2006