C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Problem with serialization

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language (comp.lang.c++)
View previous topic :: View next topic  
Author Message
okinrus
Guest





PostPosted: Wed Jun 30, 2004 4:25 am    Post subject: Problem with serialization Reply with quote



Can someone take a look at this code and figure out why
Serializable_base::add_serializer throws std::bad_alloc. The problem
seems to be the compiler because msvc++ 7.1 says
c:LibSerialLibSerial.cpp(83) : warning C4584: 'serial::E' :
base-class 'serial::A' is already a base-class of 'serial::C'
c:LibSerialLibSerial.cpp(10) : see declaration of
'serial::A'
c:LibSerialLibSerial.cpp(4Cool : see declaration of
'serial::C'


#include <vector>
#include <iostream>

//#include "Archive.h"
//
// Archive is an abstract class that defines write(int), write(float)
etc.
// But for our purposes it can be just defined to be
//
namespace serial {

class Archive { };

template<class T>
inline Archive& operator&=(Archive& ar, T& x)
{
return ar;
}

}

namespace serial {

class Serializable_base;
class Serial_holder;

// Serialize_base will store a vector of
// Serialize_action_base objects which
// will then be called back in predefined order
// at serialization
class Serialize_action_base
{
public:
virtual void serialize(Archive& ar) = 0;
};

// This should call the serialize method of a class T
template<typename T>
class Serialize_action : public Serialize_action_base
{
T* sc;
public:
Serialize_action() : sc(0)
{ }

void set_obj(T* serial)
{
sc = serial;
}

void serialize(Archive& ar)
{
if (sc != 0)
{
sc->T::serialize(ar);
}
}
};



// Serializable virtually inherits from this class to retrieve
// a unique id
class Serializable_base
{
friend class Serial_holder;
public:
Serializable_base()
{
std::cout << "Serializable_base()" << std::endl;
}

virtual ~Serializable_base()
{
std::cout << "Serializable_base destroyed" << std::endl;
}
protected:
// this is where std::bad_alloc is thrown
void add_serializer(Serialize_action_base* serializer)
{
serializers.push_back(serializer);
}
private:
typedef std::vector serializer_actions serializers;


void serialize_all(Archive& ar)
{
std::cout << "num serializers = " << serializers.size() <<
std::endl;
for (size_t i = 0; i < serializers.size(); ++i)
serializers[i]->serialize(ar);
}
};


// T is the class that inherits from this class
template<typename T>
class Serializable : public virtual Serializable_base
{
typedef T Base;

friend class Serialize_action;

// This serialize method function should be invoked within the
// Serialize_action object. It should just call the class
// who derives from this class serialize method, which
// means that any class that we should be able to make a
// given class Serializable by writing
//
// class C : public Serializable<C>
// {
// void serialize(Archive& ar) { }
// };
void serialize(Archive& ar)
{
Base* base = dynamic_cast<Base*>(this);
if (base)
base->serialize(ar);
}
public:
Serializable()
: Serializable_base()
{
std::cout << "Serializable()" << std::endl;
sa.set_obj(this);
add_serializer(&sa);
}
private:
Serialize_action sa;
};

class Serial_holder
{
public:
Serial_holder(Serializable_base* r)
: root(r)
{ }


void serialize(Archive& ar)
{
root->serialize_all(ar);
}
private:
Serializable_base* root;
};

}

#endif

//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////

// Do some tests of the serialize classes
#include "LibSerial.h"
#include <iostream>
using namespace serial;


class A : public Serializable<A>
{
int a;
int b;
int c;
public:
A() : a(1), b(2), c(3) { }

~A()
{
std::cout << "A destroyed" << std::endl;
}

void serialize(Archive& ar)
{
std::cout << "Serializing A" << std::endl;
ar &= a;
ar &= b;
ar &= c;
}
};

class B : public Serializable {
int a;
int b;
public:
B() : a(4), b(5) { }

void serialize(Archive& ar)
{
std::cout << "Serializing B" << std::endl;
ar &= a;
ar &= b;
}

};

class C : public A, public B, public Serializable {
int c;
int d;
public:
C() : c(6), d(7) { }

void serialize(Archive& ar)
{
std::cout << "Serializing C" << std::endl;
ar &= c;
ar &= d;
}
};

class D : public B, public A, public Serializable {
int e;
int f;
int g;
public:
D() : e(4), f(5), g(6)
{

}

void serialize(Archive& ar)
{
std::cout << "Serializing D" << std::endl;
ar &= e;
ar &= f;
ar &= g;
}
};

class E : public A, public C, public Serializable {
int e;
public:
E() : e(5) { }

void serialize(Archive& ar)
{
std::cout << "Serializing E" << std::endl;
ar &= e;
}
};

/// T is the class that were're testing
template void do_test(serial::Archive& ar)
{
T c;

std::cout << "testing " << typeid(c).name() << std::endl;

Serial_holder sh(&c);
sh.serialize(ar);
}

int main()
{
serial::Archive ar;
do_test
return 0;
}
Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language (comp.lang.c++) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.