Overview
Examples
Screenshots
Comparisons
Applications
Download
Documentation
Tutorials
Bazaar
Status & Roadmap
FAQ
Authors & License
Forums
Funding Ultimate++
Search on this site
Search in forums












SourceForge.net Logo
Home » U++ Library support » U++ Core » Serialize of derived classes
Serialize of derived classes [message #36357] Tue, 22 May 2012 11:15 Go to next message
koldo is currently offline  koldo
Messages: 3355
Registered: August 2008
Senior Veteran
Hello all

By doing the enclosed code MyClass data is serialized but MyClassA is not used.

How it has to be done to store the data of MyClassA including the data of the parent MyClass?

struct MyClass {
	MyClass(int data) : data(data) {};
	int data;
	void Serialize(Stream& stream) 	{stream % data;}
};

struct MyClassA : public MyClass {
	MyClassA(int dataA) : dataA(dataA) {data = dataA*2;};
	int dataA;
	void Serialize(Stream& stream) 	{stream % dataA; MyClass::Serialize(stream);}
}

struct MyClassList {
	Array<MyClass> elems;
	void Serialize(Stream& stream) 	{stream % elems;}
};

...
elems.Add(new MyClassA(12));
StoreToFile(elems, "myfile");


Best regards
Iñaki
Re: Serialize of derived classes [message #36358 is a reply to message #36357] Tue, 22 May 2012 13:08 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
koldo wrote on Tue, 22 May 2012 05:15

Hello all

By doing the enclosed code MyClass data is serialized but MyClassA is not used.

How it has to be done to store the data of MyClassA including the data of the parent MyClass?

struct MyClass {
	MyClass(int data) : data(data) {};
	int data;
	void Serialize(Stream& stream) 	{stream % data;}
};

struct MyClassA : public MyClass {
	MyClassA(int dataA) : dataA(dataA) {data = dataA*2;};
	int dataA;
	void Serialize(Stream& stream) 	{stream % dataA; MyClass::Serialize(stream);}
}

struct MyClassList {
	Array<MyClass> elems;
	void Serialize(Stream& stream) 	{stream % elems;}
};

...
elems.Add(new MyClassA(12));
StoreToFile(elems, "myfile");



This code is fundamentally wrong - elems can contain both MyClassA and MyClassB, means you need a class factory when loading the file (and then perhaps virtual Serialize).

In other words, Array::Serialize does not support polymorphic content...
Re: Serialize of derived classes [message #36372 is a reply to message #36358] Wed, 23 May 2012 09:08 Go to previous messageGo to next message
koldo is currently offline  koldo
Messages: 3355
Registered: August 2008
Senior Veteran
Hello Mirek

I understand. Saving the file is not a problem.

However when loading, first every class is created and then the class is filled.

But as the program do not know in advance the type, it does not know what constructor to use Crying or Very Sad .

So I will follow your proposal.


Best regards
Iñaki
Re: Serialize of derived classes [message #36393 is a reply to message #36372] Wed, 23 May 2012 20:40 Go to previous messageGo to next message
mdelfede is currently offline  mdelfede
Messages: 1307
Registered: September 2007
Ultimate Contributor
Koldo, please take a look at my Bazaar PolyXML class series.... It implements polymorphic serialization, which I guess is what you need.
PolyXML uses xml, but to convert it to use binary serialization should be trivial.

Max
Re: Serialize of derived classes [message #36399 is a reply to message #36393] Wed, 23 May 2012 21:52 Go to previous messageGo to next message
koldo is currently offline  koldo
Messages: 3355
Registered: August 2008
Senior Veteran
Thank you Massimo

Yes. I think your package is just what I need Smile. You will save me a lot of work.

And for sure it is not difficult to include Serialize and Jsonize support... so you will have to change package name Wink.


Best regards
Iñaki
Re: Serialize of derived classes [message #36400 is a reply to message #36399] Wed, 23 May 2012 23:00 Go to previous messageGo to next message
mdelfede is currently offline  mdelfede
Messages: 1307
Registered: September 2007
Ultimate Contributor
Beware if you change it, I'm using in my TimberStruct application to save the whole documents Smile
Please test id deeply with the PolyXMLTest application before submitting !

Ciao

Max
Re: Serialize of derived classes [message #36403 is a reply to message #36400] Thu, 24 May 2012 08:24 Go to previous messageGo to next message
koldo is currently offline  koldo
Messages: 3355
Registered: August 2008
Senior Veteran
Oh no Massimo

I do not plan to change it Smile. It is not difficult but it would require some package reengineering. This should have be made by you.

And there is also backwards compatibility... that has to remain absolutely.


Best regards
Iñaki
Re: Serialize of derived classes [message #36408 is a reply to message #36403] Thu, 24 May 2012 13:43 Go to previous messageGo to next message
mdelfede is currently offline  mdelfede
Messages: 1307
Registered: September 2007
Ultimate Contributor
Well... it should be enough to add a couple of templates :

template<class T> class WithPolyJson : public WithFactory<T>
template<class T> class WithPolySerial : public WithFactory<T>


And mimick the PolyXML series replacing Xmlize with Jsonize or Serialize.
ClassFactory template should stay unchanged, if you don't need extra features, but I guess I embedded enough of them Smile

The best way to do it would be to add a PolySerialize package that uses my PolyXML, just for ClassFactory template.
I could also separate ClassFactory from PolyXML, if needed.

The most complicated part would be to mimick the PolyXMLUnknown class, which is used to stream in unknown objects keeping their xml code. Just seldom used, mostly if you've data from a newer version of your app that provides objects not foreseen in a previous version. It's able to stream in and out some pieces of unknown data without destroying them :

template<class T> class PolyXMLUnknown : public T
{
	private:
		String tag;
		String rawXML;
	public:
		PolyXMLUnknown(String const &_tag, String const &xml)
		{
			tag = _tag;
			rawXML = xml;
		}
		
		virtual String const &IsA(void) { return CLASSFACTORY_UNKNOWN; }
		String const &GetUnknownClassName(void) { return tag; }
		
		virtual void Xmlize(XmlIO &xml)
		{
			if(xml.IsStoring())
			{
				XmlNode node = ParseXML(rawXML);
				xml.Add();
				xml.Node() = node;
			}
		}
};


You should find a way to do the same with Json and binary serialization, which I don't know if it's possible.

Max
Re: Serialize of derived classes [message #36409 is a reply to message #36408] Thu, 24 May 2012 13:52 Go to previous messageGo to next message
koldo is currently offline  koldo
Messages: 3355
Registered: August 2008
Senior Veteran
PolySerialize sounds nice. Are you going to change package name?

For a class to support XML, Json, etc, it would have to be a subclass of PolyXML, PolyJson and PolySerial?


Best regards
Iñaki

[Updated on: Thu, 24 May 2012 13:54]

Report message to a moderator

Re: Serialize of derived classes [message #36410 is a reply to message #36409] Thu, 24 May 2012 13:58 Go to previous messageGo to next message
mdelfede is currently offline  mdelfede
Messages: 1307
Registered: September 2007
Ultimate Contributor
mhhhh... better not.
You can either :

1) Create a new PolySerialize package, using PolyXML one and provide PolySerialize and PolyJsonize classes
Using PolyXML is needed just for ClassFactory.

2) I could split PolyXML into ClassFactory + PolyXML packages, and you could do as above but using the new ClassFactory package instead of PolyXML (cleaner solution...)

3) same as 2, put provide a couple of different packages for PolySerialize and PolyJsonize. That would be the cleanest solution, IMHO.

I'd rather not rename PolyXML package, because I'd have to patch some tenths of my source files.....

Max
Re: Serialize of derived classes [message #36417 is a reply to message #36410] Fri, 25 May 2012 09:17 Go to previous messageGo to next message
koldo is currently offline  koldo
Messages: 3355
Registered: August 2008
Senior Veteran
Hello Massimo

In the demo, you can see this:
/////////////////////////////////////////////////////////////////
PolyXMLArray tests
/////////////////////////////////////////////////////////////////
Array content before streaming out: 4 classes:
  class #0 is a 'Base'
    BaseData    = 'Sample data in base class'
  class #1 is a 'Derived'
    BaseData    = 'Sample data in derived class'
    DerivedData = 'Another sample data in derived class'
  class #2 is a 'Another'
    BaseData    = 'Sample data in Derived class'
    DerivedData = 'Another sample data in Derived class'
    AnotherData = '12345'
  class #3 is a 'OneMore'
    BaseData    = 'Sample data in OneMore class'
    DerivedData = 'Another sample data in OneMore class'
    AnotherData = '12'
    OneMoreData = '3.1418'

Streamed XML :

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE PolyXMLTest>
<PolyXMLTest>
        <Base>
                <BaseData>Sample data in base class</BaseData>
        </Base>
        <Derived>
                <BaseData>Sample data in derived class</BaseData>
        </Derived>
        <Another>
                <BaseData>Sample data in Derived class</BaseData>
        </Another>
        <OneMore>
                <BaseData>Sample data in OneMore class</BaseData>
        </OneMore>
</PolyXMLTest>

It seems like XML data stored only includes BaseData and does not include derived classes data. What is wrong here?


Best regards
Iñaki
Re: Serialize of derived classes [message #36420 is a reply to message #36417] Fri, 25 May 2012 17:56 Go to previous messageGo to next message
mdelfede is currently offline  mdelfede
Messages: 1307
Registered: September 2007
Ultimate Contributor
uhmmmm... really weird, even more because data is correctly restored on streaming in.... I'll check it now, hope it's not because of recent changes in Xmlize....

Max
Re: Serialize of derived classes [message #36421 is a reply to message #36420] Fri, 25 May 2012 18:32 Go to previous messageGo to next message
mdelfede is currently offline  mdelfede
Messages: 1307
Registered: September 2007
Ultimate Contributor
Hi Koldo.... got it Smile

When

Xmlize(XmlIO xml)


was replaced with
Xmlize(XmlIO &xml)


I fixed my app and PolyXML code, but not the test app, so it was using the wrong (non-virtual) Xmlize(XmlIO xml), streaming just the base class.
Please refresh from bazaar and you'll see that now it's all ok Smile

Ciao

Max
Re: Serialize of derived classes [message #36423 is a reply to message #36421] Fri, 25 May 2012 21:40 Go to previous message
koldo is currently offline  koldo
Messages: 3355
Registered: August 2008
Senior Veteran
Thank you.

Best regards
Iñaki
Previous Topic: Value: String to int - problem or feature?
Next Topic: Problem with GetTickCount on Linux
Goto Forum:
  


Current Time: Fri Mar 29 15:26:19 CET 2024

Total time taken to generate the page: 0.01909 seconds