Click here to Skip to main content
Click here to Skip to main content

A serialization primer - Part 3

By , 23 Jun 2005
 

This article is the third of a 3 part tutorial on serialization.

  • Part 1 introduces the basics of serialization.
  • Part 2 explains how to gracefully handle reading invalid data stores and support versioning.
  • Part 3 describes how to serialize complex objects.

In the previous two parts, we learned how to provide robust support for serialization in general. In this article, we'll learn the specific rules for serializing any kind of object. There are 4 general cases to consider. Each case builds on the previous one.

  • Serializing a simple class
  • Serializing a derived class
  • Serializing a homogenous collection class
  • Serializing a heterogenous collection class
Our serialize() method will return one of these status codes:
  • Success
  • InvalidFormat
  • UnsupportedVersion
  • ReadError
  • WriteError

Serializing a simple class

A "simple class" is defined as an object that has no parent class and is not a collection class. To serialize a simple class, do the following:
  1. Serialize the object's signature and version
  2. Serialize the object's members (if any)
In the following example, the class Point contains 2 int members that represent the coordinates of a point. The object's signature and version are defined as static members (m_strSignature and m_nVersion), since they apply to all instances of Point.
  int Point::serialize
    (CArchive* pArchive)
  {
    ASSERT (pArchive != NULL);

    // Step 1: Serialize signature and version
    int nVersion;
    try {
      if (pArchive->IsStoring()) {
          (*pArchive) << Point::m_strSignature;
          (*pArchive) << Point::m_nVersion;
      } else {
          CString strSignature;
          (*pArchive) >> strSignature;
          if (strSignature != Point::m_strSignature)
             return (Status::InvalidFormat);
          (*pArchive) >> nVersion;
          if (nVersion > Point::m_nVersion;)
             return (Status::UnsupportedVersion);
      }

      // Step 2: Serialize members
      if (pArchive->IsStoring()) {
          (*pArchive) << m_nX;
          (*pArchive) << m_nY;
      } else {
          (*pArchive) >> m_nX;
          (*pArchive) >> m_nY;
      }
    }
    catch (CException* pException) {
      // A read/write error occured
      pException->Delete();
      if (pArchive->IsStoring())
        return (Status::WriteError);
      return (Status::ReadError);
    }

    // Object was successfully serialized
    return (Status::Success);
  }

Serializing a derived class

For the purpose of this discussion, a derived class is one that is derived from a simple class and is not a collection class. To serialize a derived class, do the following:

  1. Serialize the object's signature and version
  2. Serialize the object's base class << additional step
  3. Serialize the object's members (if any)
In the following example, the class ColoredPoint is derived from Point and contains an additional int member called m_nColor, which specifies the point's color. Like all serializable classes, ColoredPoint also defines a static signature and version.
  int ColoredPoint::serialize
    (CArchive* pArchive)
  {
    ASSERT (pArchive != NULL);

    // Step 1: Serialize signature and version
    int nVersion;
    try {
      if (pArchive->IsStoring()) {
          (*pArchive) << ColoredPoint::m_strSignature;
          (*pArchive) << ColoredPoint::m_nVersion;
      } else {
          CString strSignature;
          (*pArchive) >> strSignature;
          if (strSignature != ColoredPoint::m_strSignature)
             return (Status::InvalidFormat);
          (*pArchive) >> nVersion;
          if (nVersion > ColoredPoint::m_nVersion;)
             return (Status::UnsupportedVersion);
      }

      // Step 2: Serialize the base class
      int nStatus = Point::serialize (pArchive);
      if (nStatus != Status::Success)
         return (nStatus);

      // Step 3: Serialize members
      if (pArchive->IsStoring())
         (*pArchive) << m_nColor;
      else
         (*pArchive) >> m_nColor;
    }
    catch (CException* pException) {
      // A read/write error occured
      pException->Delete();
      if (pArchive->IsStoring())
        return (Status::WriteError);
      return (Status::ReadError);
    }

    // Object was successfully serialized
    return (Status::Success);
  }

Serializing a homogenous collection class

Homogenous collection classes are used to store dynamically sized collections of the same type of object. To serialize a homogenous collection class, do the following:

  1. Serialize the object's signature and version
  2. Serialize the object's base class (if any)
  3. Serialize the number of items in the collection << additional step
  4. Serialize each object in the collection << additional step
  5. Serialize the object's other members (if any)
In the following example, the class ColoredPointList is a collection of ColoredPoint objects. To keep things simple, ColoredPointList uses a CPtrArray to store objects. Like all serializable classes, ColoredPointList also defines a static signature and version. Here's what ColoredPointList looks like:
  class ColoredPointList
  {
    // Construction/destruction
    public:
      ColoredPointList::ColoredPointList();
      virtual ColoredPointList::~ColoredPointList();

    // Attributes
    public:
      static const CString m_strSignature;
      static const int m_nVersion;

    // Operations
    public:
      int serialize (CArchive* pArchive);

    // Members
    protected:
      CPtrArray m_coloredPoints;
  }
And here's how we serialize it:
  int ColoredPointList::serialize
    (CArchive* pArchive)
  {
    ASSERT (pArchive != NULL);
    int nStatus = Status::Success;

    // Step 1: Serialize signature and version
    int nVersion;
    try {
      if (pArchive->IsStoring()) {
          (*pArchive) << ColoredPointList::m_strSignature;
          (*pArchive) << ColoredPointList::m_nVersion;
      } else {
          CString strSignature;
          (*pArchive) >> strSignature;
          if (strSignature != ColoredPointList::m_strSignature)
             return (Status::InvalidFormat);
          (*pArchive) >> nVersion;
          if (nVersion > ColoredPointList::m_nVersion;)
             return (Status::UnsupportedVersion);
      }

      // Step 2: Serialize base class (if any)
      //
      // Nothing to do since ColoredPointList isn't derived from anything.
      // But if it was derived from BaseColoredPointList, we'd do:
      //
      // nStatus = BaseColoredPointList::serialize (pArchive);
      // if (nStatus != Status::Success)
      //    return (nStatus);

      // Step 3: Serialize number of items in collection
      int nItems = 0;
      if (pArchive->IsStoring()) {
           nItems = m_coloredPoints.GetSize();
           (*pArchive) << nItems;
      } else
           (*pArchive) >> nItems;

      // Step 4: Serialize each object in collection
      for (int nObject=0; (nObject < nItems); nObject++) {

          // 4a: Point to object being serialized
          ColoredPoint* pColoredPoint = NULL;
          if (pArchive->IsStoring())
             pColoredPoint = (ColoredPoint *) m_coloredPoints.GetAt (nObject);
          else
             pColoredPoint = new ColoredPoint();
          ASSERT (pColoredPoint != NULL);

          // 4b: Serialize it
          nStatus = pColoredPoint->serialize (pArchive);
          if (nStatus != Status::Success)
             return (nStatus);
          if (!pArchive->IsStoring())
             m_coloredPoints.Add (pColoredPoint);
      }

      // Step 5: Serialize object's other members (if any)
      //
      // Nothing to do since ColoredPointList doesn't have any other
      // members. But if it contained an int (m_nSomeInt) and a Foo
      // object (m_foo), we'd do:
      //
      // if (pArchive->IsStoring())
      //    (*pArchive) << m_nSomeInt;
      // else
      //    (*pArchive) >> m_nColor;
      //
      // nStatus = m_foo::serialize (pArchive);
      // if (nStatus != Status::Success)
      //    return (nStatus);

    }
    catch (CException* pException) {
      // A read/write error occured
      pException->Delete();
      if (pArchive->IsStoring())
        return (Status::WriteError);
      return (Status::ReadError);
    }

    // Object was successfully serialized
    return (Status::Success);
  }

Serializing a heterogenous collection class

Heterogenous collection classes are used to store dynamically sized collections of potentially different types of objects. To serialize a heterogenous collection class, do the following:

  1. Serialize the object's signature and version
  2. Serialize the object's base class (if any)
  3. Serialize the number of items in the collection
  4. For each object in the collection
    (a) serialize that object's signature << additional step
    (b) then serialize that object
  5. Serialize the object's other members (if any)
You'll notice the only additional step in serializing heterogenous collections is 4(a), where we serialize each object's signature before serializing the object itself. This comes in handy when reading back our data. When we serialized a homogeous collection, we dealt with objects of the same type (ColoredPoints in the previous example). To read in a ColoredPoint, we constructed it on the heap and then called its serialize() method.
  ColoredPoint* pColoredPoint = new ColoredPoint();
  nStatus = pColoredPoint->serialize (pArchive);
When we're dealing with heterogenous collections, we need to know the type of object we're reading back in, before actually serializing it. That's where the object's signature comes in. Since we saved the signature on the way out, we can construct an object of the appropriate type on the way in.
  // Read object signature
  CString strSignature;
  pArchive >> strSignature;

  // Construct object of appropriate type
  ISerializable* pObject = NULL;
  if (strSignature == ColoredPoint::m_strSignature)
     pObject = new ColoredPoint();
  else
    if (strSignature == Line::m_strSignature)
       pObject = new Line();
    else
       if (strSignature == Rectangle::m_strSignature)
          pObject = new Rectangle();
       else
          return (Status::InvalidFormat);
  ASSERT (pObject != NULL);

  // Read it back in
  nStatus = pObject->serialize (pArchive);
In the above code fragment, ColoredPoint, Line and Rectangle are all (eventually) derived from a common base class ISerializable, which is nothing more than an abstract base class containing only pure virtual methods (in other words, an "interface"). ISerializable defines the methods getSignature(), getVersion() and serialize().
  class ISerializable
  {
    // Construction/destruction
    public:
      ISerializable::ISerializable()
        { }
      virtual ISerializable::~ISerializable()
        { }

    // Operations
    public:
      // Get the object's signature
      virtual CString getSignature() = 0;

      // Get the object's version
      virtual int getVersion() = 0;

      // Serialize the object
      virtual int serialize (CArchive* pArchive) = 0;
  }
OK, let's serialize our heterogenous collection. In the following example, the class ShapeList is a collection of varying numbers of ColoredPoint, Line and Rectangle objects, all of which derive from ISerializable. You can look upon these classes as "implementing the ISerializable interface".
  int ShapeList::serialize
    (CArchive* pArchive)
  {
    ASSERT (pArchive != NULL);
    int nStatus = Status::Success;

    // Step 1: Serialize signature and version
    int nVersion;
    try {
      if (pArchive->IsStoring()) {
          (*pArchive) << ShapeList::m_strSignature;
          (*pArchive) << ShapeList::m_nVersion;
      } else {
          CString strSignature;
          (*pArchive) >> strSignature;
          if (strSignature != ShapeList::m_strSignature)
             return (Status::InvalidFormat);
          (*pArchive) >> nVersion;
          if (nVersion > ShapeList::m_nVersion;)
             return (Status::UnsupportedVersion);
      }

      // Step 2: Serialize base class (if any)
      //
      // Nothing to do since ShapeList isn't derived from anything.
      // But if it was derived from BaseShapeList, we'd do:
      //
      // nStatus = BaseShapeList::serialize (pArchive);
      // if (nStatus != Status::Success)
      //    return (nStatus);

      // Step 3: Serialize number of items in collection
      int nItems = 0;
      if (pArchive->IsStoring()) {
           nItems = m_shapes.GetSize();
           (*pArchive) << nItems;
      } else
           (*pArchive) >> nItems;

      // Step 4: Serialize each object in collection
      for (int nObject=0; (nObject < nItems); nObject++) {

          // 4a: First serialize object's signature
          CString strSignature;
          if (pArchive->IsStoring())
             (*pArchive) << pObject->getSignature();
          else
             (*pArchive) >> strSignature;

          //
          // 4b: Then serialize object
          //

          // 4b (1): Point to object being serialized
          ISerializable* pObject = NULL;
          if (pArchive->IsStoring())
             pObject = (ISerializable *) m_shapes.GetAt (nObject);
          else {
             if (strSignature == ColoredPoint::m_strSignature)
                pObject = new ColoredPoint();
             else
               if (strSignature == Line::m_strSignature)
                  pObject = new Line();
               else
                  if (strSignature == Rectangle::m_strSignature)
                     pObject = new Rectangle();
                  else
                     return (Status::InvalidFormat);
          }
          ASSERT (pObject != NULL);

          // 4b (2): Serialize it
          nStatus = pObject->serialize (pArchive);
          if (nStatus != Status::Success)
             return (nStatus);
          if (!pArchive->IsStoring())
             m_shapes.Add (pObject);
      }

      // Step 5: Serialize object's other members (if any)
      //
      // Nothing to do since ShapeList doesn't have any other
      // members.  But if it contained an int (m_nSomeInt) and
      // a Foo object (m_foo), we'd do:
      //
      // if (pArchive->IsStoring())
      //    (*pArchive) << m_nSomeInt;
      // else
      //    (*pArchive) >> m_nColor;
      //
      // nStatus = m_foo::serialize (pArchive);
      // if (nStatus != Status::Success)
      //    return (nStatus);

    }
    catch (CException* pException) {
      // A read/write error occured
      pException->Delete();
      if (pArchive->IsStoring())
        return (Status::WriteError);
      return (Status::ReadError);
    }

    // Object was successfully serialized
    return (Status::Success);
  }

Class Factory

You can replace the ugly if statement in the code fragment by using a "class factory" to serve up a new instance of a class based on its signature. Here are some articles you might want to look at: Although the articles vary in complexity, the basic idea behind them is the same. A class factory is little more than a class that offers an appropriately named static method (eg: create()) that serves up an object of a specific type. You could hide the nasty if statement in the factory's create() method, cleaning up the code a bit.
  ...
  // Construct object of appropriate type
  ISerializable* pObject = MyClassFactory::create (strSignature);
  ASSERT (pObject != NULL);
  ...

Conclusion

Although this primer refers to MFC objects like CString and CPtrArray, serialization is not specific to MFC. It's a common operation performed by any software that needs to save and restore information to and from persistent storage.

Revision History

  • 24 Jun 2005
    Fixed typo in example code (thanks, J Roy!)
  • 13 Jun 2005
    Fixed typos in example code (thanks, Mohammed Tarik!)
  • 26 Apr 2004
    Fixed typo in example code (thanks, David Paul Jones!)
  • 24 Apr 2004
    Added much needed examples.
  • 18 Feb 2002
    Initial version.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Ravi Bhavnani
Technical Lead
Canada Canada
Member
Ravi Bhavnani is an ardent fan of Microsoft technologies who loves building Windows apps, especially PIMs, system utilities, and things that go bump on the Internet. During his career, Ravi has developed expert systems, desktop imaging apps, marketing automation software, EDA tools, a platform to help people find, analyze and understand information, trading software for institutional investors and advanced data visualization solutions. He currently works for a company that provides enterprise workforce management solutions to large clients.
 
His interests include the .NET framework, reasoning systems, financial analysis and algorithmic trading, NLP, CHI and UI design. Ravi holds a BS in Physics and Math and an MS in Computer Science and was a Microsoft MVP (C++ and C# in 2006 and 2007). He is also the co-inventor of 2 patents on software security and generating data visualization dashboards. His claim to fame is that he crafted CodeProject's "joke" forum post icon.
 
Ravi's biggest fear is that one day he might actually get a life, although the chances of that happening seem extremely remote.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralMy vote of 5memberpeoria12325 Jan '13 - 12:13 
good explanation..
QuestionSerializing Clistcontrolmemberpeoria12325 Jan '13 - 12:11 
Nice work.. I understand the basic serialization ..But How I can serialize the CListcontrol ? it has some columns editable and some has comboboxes.I want to add two buttons on dialogbox for one to save the list and second for load the list.
 
Thank you.
QuestionDoes it support multi-inheritance?membertransoft18 May '09 - 2:04 
Hi
 
I am looking for a method to support multi-inheritance. I did not find the multi-inheritance in the article.
 
Thanks
AnswerRe: Does it support multi-inheritance?memberRavi Bhavnani18 May '09 - 5:46 
Correct, this article does not directly address multiple inheritance (which imho, has more drawbacks than advantages). However, for the purpose of serialization, you can handle multiply inherited objects by serializing (and deserializing) the "multiple base classes" in step 2 of "Serializing a derived class".
 
/ravi
 
My new year resolution: 2048 x 1536
Home | Articles | My .NET bits | Freeware
ravib(at)ravib(dot)com

GeneralRe: Does it support multi-inheritance?membertransoft18 May '09 - 5:54 
Thanks
GeneralNice articles.memberquakeboy28 Nov '08 - 11:48 
You have written them very clearly and precisely without extra overloaded info. Interesting read.
 
But I have some queries. What if I have a complex object which has pointers to other objects and need to restore them back. Consider a heterogenous list of pointers to objects. And each of those object contain pointers which point to other objects in the same list. What if each object in the hetero list have a list inside them holding other objects.
 
Main query is how to serialize a base class pointer.
AnswerRe: Nice articles.memberRavi Bhavnani28 Nov '08 - 11:52 
Thanks!
 
Serializing pointers won't work for the obvious reasons that memory locations can (and perhaps almost certainly will) change during deserialization (loading). For this reason, it's better to use persistent references such as ids/Guids instead of direct pointers.
 
Hope this helps.
 
/ravi
 
My new year resolution: 2048 x 1536
Home | Articles | My .NET bits | Freeware
ravib(at)ravib(dot)com

GeneralRe: Nice articles.memberquakeboy29 Nov '08 - 6:51 
So Boost is far better that way isn't it.
 
Is MFC serialization inferior to that ?
 
http://quakeboythecoder.blogspot.com

GeneralRe: Nice articles.memberRavi Bhavnani29 Nov '08 - 7:27 
quakeboy wrote:
Is MFC serialization inferior to that ?

 
Actually it's not MFC, it's the problem with any language (in this case C++), which uses direct references to memory locations (i.e. pointers). Since the OS' memory management system can't guarantee a piece of data will be stored in the same location across program runs, it doesn't make sense to persist this information during serialization, even though it's possible to so, since a pointer is nothing more than a 32 bit value.
 
/ravi
 
My new year resolution: 2048 x 1536
Home | Articles | My .NET bits | Freeware
ravib(at)ravib(dot)com

GeneralRe: Nice articles.memberquakeboy29 Nov '08 - 10:30 
Ok. I have been reading Boost serialization library documentation recently. It assured to serialize pointers also. Even pointers to base classes, a list of pointers etc. That means the entire application state can be serialized isn't it ?
 
Or have I misunderstood that ? Can you please help me if you have time to verify it.. I think it will be useful to others also.
 
http://www.boost.org/doc/libs/1_37_0/libs/serialization/doc/index.html[^]
 
http://quakeboythecoder.blogspot.com

GeneralRe: Nice articles.memberRavi Bhavnani30 Nov '08 - 7:23 
Yes, Boost appears to support deep pointer serialization. But this means they're doing something special to make this happen. You can do the same thing using MFC by replacing the values of pointers with GUIDs (on the way out), then remapping GUIDs to pointers during deserialization.
 
Having moved away from C/C++ to GC languages (Java and C#), I prefer to use pointer/reference agnostic GUIDs to store links to other objects. I find this scheme to be more robust and intuitive.
 
/ravi
 
My new year resolution: 2048 x 1536
Home | Articles | My .NET bits | Freeware
ravib(at)ravib(dot)com

GeneralI have found for moths,thank you very much!!!memberLynne.Hoo16 Dec '07 - 20:04 
I have found for moths,thank you very much!!! Smile | :)
GeneralAfter all these years, i got it!!memberpointer17 Nov '07 - 7:17 
Hello Ravi,
 
Now i became master of serialization!!
Thanx a lot!!
You have my 5!!
GeneralRe: After all these years, i got it!!memberRavi Bhavnani17 Nov '07 - 7:21 
Thanks for your comments! Rose | [Rose] Glad I could be of help!
 
/ravi
 
This is your brain on Celcius
Home | Music | Articles | Freeware | Trips
ravib(at)ravib(dot)com

QuestionWhen and where CArchive& AFXAPI operator>>(CArchive& ar,class_name* &pOb) is calledmemberxxq3121716 Apr '07 - 15:48 
Many articles tell me that when i want to make a class serializable in VC 6.0 MFC projects,i need to:
1.Deriving your class from CObject (or from some class derived from CObject ).
2.Overriding the Serialize member function.
3.Using the DECLARE_SERIAL macro in the class declaration.
4.Defining a constructor that takes no arguments.
5.Using the IMPLEMENT_SERIAL macro in the implement files.
I know the DECLARE_SERIAL macro declare an operator in source files.
#define IMPLEMENT_SERIAL(class_name,base_class_name,wSchema)\
.............................
CArchive& AFXAPI operator>>(CArchive& ar,class_name* &pOb)\
{ pOb=(class_name*)ar.ReadObject(RUNTIME_CLASS(class_name));
return ar;
}
I really do not know when and where operator>>(CArchive& ar,class_name* &pOb) is called.
I find when reading an object from a persistent storage medium,_AFX_INLINE CCArchive& AFXAPI operator>>(CArchive& ar,CObject*& pOb){pOb=ar.ReadObject(NULL);return ar;} is called not operator>>(CArchive& ar,class_name* &pOb).
Can you give me some examples ?
My english is poor,but i really want get your help!!
Thanks!
AnswerRe: When and where CArchive& AFXAPI operator>>(CArchive& ar,class_name* &pOb) is calledmemberxxq3121717 Apr '07 - 15:28 
Thank you for your reply!
I think i should read your tutorials carefully first,maybe i could understand MFC serialization.Your article is very nice,it's good help for me!I am a chinese and not used to speaking english,But i relly thank you !
GeneralSome remarks (or bug fixes)membercristitomi14 Feb '07 - 1:49 
Hi Ravi!
I have implemented a complete serialization application using the 3rd part and I want to add some remarks that I noticed during implementation.
They all have to do with the serialization of a heterogenous collection class.
 
1) The first problem appears in:
 
// 4a: First serialize object's signature
CString strSignature;
if (pArchive->IsStoring())
   (*pArchive) << pObject->getSignature();
else
   (*pArchive) >> strSignature;
At this point pObject is unknown and you will get a compiler error.
 
2) The second problem:
 
// 4b (1): Point to object being serialized
ISerializable* pObject = NULL;
if (pArchive->IsStoring())
   pObject = (ISerializable *) m_shapes.GetAt (nObject);
This is also wrong if you create pObject at this point because earlier you serialized it's signature and this is unwanted behaviour.
 
3) The third problem:
 
if (strSignature == ColoredPoint::m_strSignature)
   pObject = new ColoredPoint();
This actually doesn't compare two strings by value and you will get unwanted behaviour.
Try
 
if (strcmp(strSignature, ColoredPoint::m_strSignature) == 0)
   pObject = new ColoredPoint();
instead.
 
I am in love with VC++
GeneralRe: Some remarks (or bug fixes)membercristitomi14 Feb '07 - 2:37 
I am going to present in this message solutions of the problems presented earlier.
In other words, the serialize function of ShapeList should look like this:
 
int ShapeList::serialize(CArchive* pArchive)
{
   ...........................................
 
   // 4. serialize each object in collection
   for (int nObject = 0; (nObject < nItems); nObject++)
   {
      // a NULL pointer of type ISerializable should be declared here
      ISerializable* pObject = NULL;
      CString strSignature;
 
      // 4.a first serialize object's signature
      if(pArchive->IsStoring())
      {
        // at this point in case of storing get the corresponding object
        // from the array
	pObject = (ISerializable* )m_shapes.GetAt(nObject);
        // make sure it is not NULL
	ASSERT(pObject != NULL);
        // for the respective object serialize it's signature
	(*pArchive) << pObject->GetSignature();
      }
      else
      {
	(*pArchive) >> strSignature;
      }
 
      // 4.b then serialize the object
      if(!pArchive->IsStoring())
      {
	if(strcmp(strSignature, Line::m_strSignature) == 0)
           pObject = new Line();
	else if(strcmp(strSignature, ColoredPoint::m_strSignature) == 0)
	   pObject = new ColoredPoint();
	else if(strcmp(strSignature, Rectangle::m_strSignature) == 0)
	   pObject = new Rectangle();
	else
	   return (Status::InvalidFormat);
      }
   }
   ...............................................
}
That's all. Now it will work.
 
Anyway, I will present in another message some hints for implementing the serialization process for a heterogenous collection class, since is the far most interesting case of serialization.
If anyone is interested, mail me and I will send you the source code I have done.
 
I am in love with VC++
GeneralVery nice article indeedmembercristitomi13 Feb '07 - 5:33 
I have read the article and all I can say is "Very well done".
All your three articles on serialization were very helpful to me.
You have my five.
Also I like your "clear" way of presenting things.
Best regards.
 
I am in love with VC++
GeneralRe: Very nice article indeedmemberRavi Bhavnani13 Feb '07 - 5:44 
Thanks for the kind words, Crisi! Blush | :O
 
/ravi
 
This is your brain on Celcius
Home | Music | Articles | Freeware | Trips
ravib(at)ravib(dot)com

GeneralCArray Object Serializationmembermurtazadhari31 Aug '06 - 9:45 
Hi. i want to serialize an object of CArray. how could i do this.
 
CArray<Abc,Abc&> EFG;
 
EFG contains many objects of ABC, and ABC is a class that contains Two Variable CString and byte * . please any one could tell how can i serialize a whole object of CArray (EFG)in a file .
 
Thank you
 
Murtaza Tahir Ali Dhari
AnswerRe: CArray Object SerializationmemberRavi Bhavnani31 Aug '06 - 9:51 
Murtaza, see the section "Serializing a homogenous collection class" in this (part 3) article of the series. Basically, you'll need to write a serialize method for class ABC and one for the collection.
 
/ravi
 
My new year's resolution: 2048 x 1536
Home | Music | Articles | Freeware | Trips
ravib(at)ravib(dot)com

GeneralRe: CArray Object Serializationmembermurtazadhari1 Sep '06 - 7:33 
i had read it. but i m still not able to understand the serialization and desserialization of CArray Object .
 
how could we use the function of CArray .
 
e.g
 
EFG.Serialize(CArchive); //EFG object of CArray
 
wht is the purpose if this function .
 
please show if u have any code for this function used for serialization and deserialization.
 
and thanks for Reply.
 
Murtaza Tahir Ali
QuestionHow to implement versioning for CDocumentmemberjustsuraj30 Jul '06 - 21:02 
how can I use VERSIONABLE_SCHEMA for a CDocument class, so that i can load/save older versions of document.
 
no me no fun, know me know fun Smile | :)
Suraj
AnswerRe: How to implement versioning for CDocumentmemberRavi Bhavnani31 Jul '06 - 2:04 
Part 2[^] of my tutorial describes how to support versioning. For details on using VERSIONABLE_SCHEMA, see this[^] article.
 
/ravi
 
My new year's resolution: 2048 x 1536
Home | Music | Articles | Freeware | Trips
ravib(at)ravib(dot)com

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web01 | 2.6.130523.1 | Last Updated 24 Jun 2005
Article Copyright 2002 by Ravi Bhavnani
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid