Boost logo

Boost :

From: Ares Lagae (ares.lagae_at_[hidden])
Date: 2003-01-12 11:44:42


> If you're willing to intrude on the design of Foo, there are much
> cleaner solutions using friend. However, non-intrusive serialization
> should generally be possible even for classes which are
> well-encapsulated.

ok (i'm just making suggestions for the sake of discussion here)

suppose we do it like this:

introduce metaclass information for each class:
(adapted java Class naming)

/* Class<C> represents class C */
template <class C>
class Class {
public:
        Class(char * name) : m_name(0) {
                m_name = strdup(name);
        }
        ~Class() {
                free(m_name);
        }
        static void serialize(C value) {
                /*
                for each DataMember_base<C> in list of datamembers
                        DataMember_base<C>.serialize(value)
                */
        }
private:
        char * m_name;
        // a list of DataMember_base<C>: all the data members of class C
};

/* DataMember_base<C> represents a data member of class C */
template <class C>
class DataMember_base {
public:
        /* serialize the datamember of instance */
        virtual void serialize(C & instance) = 0;
};

/* DataMember<C, T> represents a data member of class C with type T */
template <class C, typename T>
class DataMember : public DataMember_base<C> {
        public:
                DataMember(T C::*ptr, char * name) : m_ptr(ptr), m_name(0) {
                        m_name = strdup(name);
                }
                ~DataMember() {
                        free(m_name);
                }
                void setValue(C & instance, T value) {
                        instance.*m_ptr = value;
                }
                T getValue(C & instance) {
                        return instance.*m_ptr;
                };
                /* ask my class to serialize my value */
                void serialize(C & instance) {
                        Class<T>::serialize(getValue(instance));
                }
        private:
                T C::*m_ptr;
                char * m_name;
};

next, we provide template specialisations for class<primitive type>
for example:

template<>
class Class<int> {
        public:
                static void serialize(int value) {
                        printf("Class<int>::serialize(%d)\n", value);
                        /* Serializer.serializeInt(value) */
                }
};

with this mechanism the user has the choise between intrusive and non-intrusive serialisation
- intrusive: in class A, initialize a Class<A> object with the datamembers
- non intrusive: for class B, specialize the Class<B> template

a Class<C> object could maintain a flag m_initialized, set to 1 if C initialized a Class<C> object (intrusive)
while serializing, this flag could be checked in the non specialized Class<C> serialize() method and a sensible error message could be printed ("error: dont how to serialize C, intrusively initialize Class<C>, or provide a Class<C> template
specialisation")

does this make sense ?

Best regards,
Ares Lagae


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk