 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
okinrus Guest
|
Posted: Wed Jun 30, 2004 4:25 am Post subject: Problem with serialization |
|
|
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(4 : 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 |
|
 |
|
|
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
|
|