Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations bkrike on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Problem with serialization of embedded objects

Status
Not open for further replies.

mcowen

Programmer
Oct 21, 2001
134
GB
Hi all,

I have classes two classes CContainer and CTest. CContainer holds a protected member variable pointer to a CTest object. The purposes of these 2 classes is to demonstrate the serialization of embedded objects. It works but when I try to add a CArray of CTest objects to CContainer the program just crashes as soon as I start it. I have had to add a copy constructor and operator= functions to allow instantiations of CTest to be added to CArray. Here is what I have...


*********** CContainer ****************


class CContainer : public CObject
{
DECLARE_SERIAL(CContainer)
public:
void Serialize(CArchive &ar);
void Display();
CContainer();
CContainer(int d, CTest * ptrCT);
private:
int a; //bit of sample data for CContainer class
CTest * ptrCss CTest : public CObject //Here's the embedded data
{
DECLARE_SERIAL(CTest)
public:
//Overide
void Serialize(CArchive &ar);
CTest(int a, float b);
CTest(const CTest& rhs);
const CTest& operator=(CTest& rhs);
void Display();
CTest();
virtual ~CTest();

protected:
int x;
float y;
CArray<CTest, CTest> array; <<<<<ADDED
};

IMPLEMENT_SERIAL(CContainer,CObject,1)

CContainer::CContainer()
{

}

CContainer::CContainer(int d, CTest * ptrCT) //a bit of data + ptr to a CTest object
{
ptrCTest = ptrCT;
a = d;
CTest r(30,25); <<<<<ADDED
array.Add(r); <<<<<ADDED
}

void CContainer::Display()
{
cout <<endl <<&quot;Container data : &quot; << a;
ptrCTest->Display();
}

void CContainer::Serialize(CArchive &ar)
{
CObject::Serialize(ar);
if(ar.IsStoring ())
ar << a << ptrCTest; //Store object's data
else ar >> a >> ptrCTest; //Load object's data

}

*********************CTest******************

class CTest : public CObject
{
//MAcro needed here
DECLARE_SERIAL(CTest)
public:
//Overide
void Serialize(CArchive &ar);
CTest(int a, float b);
CTest(const CTest& rhs);
const CTest& operator=(CTest& rhs);
void Display();
CTest();
virtual ~CTest();

protected:
int x;
float y;
};


IMPLEMENT_SERIAL(CTest,CObject,1)

CTest::CTest()
{

}

CTest::~CTest()
{

}

void CTest::Display()
{
cout << endl <<&quot;CTest data : &quot; << &quot;x : &quot; << x << &quot; y : &quot; <<y <<endl;
}

CTest::CTest(int a, float b)
{
x =a; y =b;
}

//This is it
void CTest::Serialize(CArchive &ar)
{
CObject::Serialize(ar); //Serialize base class data (redundant here)
if(ar.IsStoring ()) //Decide whether to store or load data
ar << x << y; //Store object's data
else ar >> x >> y; //Load object's data

}

CTest::CTest(const CTest& rhs)
{
x = rhs.x;
y = rhs.y;
}

const CTest& CTest::eek:perator=(CTest& rhs)
{
this->x = rhs.x;
this->y = rhs.y;
return *this;
}

*********************MAIN************** (Not changed)

void main()
{
//Create an embedded object (CTest) on the heap
// & pass address as parameter to newly created container object
CContainer c1(44,new CTest(23,44.55));

// Display c1 data before serializing
cout << endl << &quot;Display c1 data before serializing&quot; <<endl;
c1.Display();

//Create a CFile object in readwrite mode
//Create CArchive object(to store data) linked to CFile object
try
{ CFile f(_T (&quot;test1&quot;),CFile::modeReadWrite | CFile::modeCreate);
CArchive ar(&f,CArchive::store);

//Serialize Container object to store
c1.Serialize (ar);

//Tidy up
ar.Close();
f.Close();

//Create new CFile object in read mode
//Create CArchive object(to load data) linked to CFile object
CFile f1(_T (&quot;test1&quot;),CFile::modeRead);
CArchive as(&f1,CArchive::load);

//Create new Container object to load data into (just to show it really works!)
CContainer c2;
//Load the data
c2.Serialize (as);

//Display c2 CContainer object's data after loading
cout << endl << &quot;Display c2 data after loading&quot; <<endl;
c2.Display ();
} catch (CFileException* e)
{
e->ReportError();
e->Delete();
}

}

*********************************

When i run the program without making any changes it runs. If I then make the changes the program fails. I then remove the added parts and the program still fails! How can this happen? If the program reverts to how it orignally was then what can be stopping it from working?
The aim of all this is to serialize an array. If anyone has an example it would be much appreciated.

Regards
Matt
 
I used the following (more or less) broken up into several files with your main() or very close and it seemed to work OK

Code:
//test.h
#include <iostream.h>
class CTest : public CObject  
{
  DECLARE_SERIAL(CTest)
public:
  //Overide 
  CTest();
  CTest(int a, float b);
  CTest(const CTest& rhs);
  virtual ~CTest();
	
  const CTest& operator=(CTest& rhs);
  const CTest& operator=(CTest *rhs);
  void Display();
  void Serialize(CArchive &ar);
	
protected:
  int x;
  float y;
};

//test.cpp

#include &quot;Test.h&quot;

IMPLEMENT_SERIAL(CTest,CObject,1)

CTest::CTest()
{
}

CTest::~CTest()
{
}

void CTest::Display()
{
  cout <<&quot;\nCTest data : &quot; << &quot;x : &quot; << x << &quot;  y : &quot; <<y;
}

CTest::CTest(int a, float b)
{
  x =a; y =b;
}

void CTest::Serialize(CArchive &ar)
{
  CObject::Serialize(ar);
  if(ar.IsStoring ())
    ar << x << y;
  else
    ar >> x >> y;
}

CTest::CTest(const CTest& rhs)
{
  x = rhs.x;
  y = rhs.y;
}

const CTest& CTest::operator=(CTest& rhs)
{
  this->x = rhs.x;
  this->y = rhs.y;
  return *this;
}

const CTest& CTest::operator=(CTest *rhs)
{
  this->x = rhs->x;
  this->y = rhs->y;
  return *this;
}

//container.h

#include &quot;test.h&quot;
#include <afx.h>
#include <afxtempl.h>
#include <iostream.h>
class CContainer : public CObject  
{
  DECLARE_SERIAL(CContainer)
public:
  CContainer();
  CContainer(int d, CTest * ptrCT); 
  ~CContainer();
  void Display();

  void Serialize(CArchive &ar);

private:
  int a;    //bit of sample data for CContainer class
  CArray<CTest, CTest> array;
  CTest * ptrCTest;  //Here's the embedded data
};

//container.cpp
#include &quot;Container.h&quot;

IMPLEMENT_SERIAL(CContainer,CObject,1)

CContainer::CContainer()
{
}

CContainer::~CContainer()
{
}

CContainer::CContainer(int d, CTest * ptrCT)
{
  a = d;
  CTest r(30,25);
  array.Add(r);
  r = ptrCT;
  array.Add(r);
}

void CContainer::Display()
{
  cout <<endl <<&quot;Container data : &quot; << a;
  int x = array.GetSize();
  for(int i=0;i<x;i++)
  {
    array[i].Display();
  }
}

void CContainer::Serialize(CArchive &ar)
{
  int nArraySize = array.GetSize();
  CObject::Serialize(ar);
  if(ar.IsStoring ())
  {
    ar << a << nArraySize;
    for(int i = 0; i<nArraySize;i++)
    {
      array[i].Serialize(ar);
    }
  }
  else
  {
    CTest tTemp;
    ar >> a >> nArraySize;
    for(int i = 0; i<nArraySize;i++)
    {
      tTemp.Serialize(ar);
      array.Add(tTemp);
    }
  }
}
 
Four information purposes...

There is indeed nothing wrong with the code. It looks to be an issue with my project settings.

Thanks to snuv
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top