views:

316

answers:

1

I have a complex network of objects connected with QSharedPointers and QWeakPointers. Is there a simple way to save/load them with Boost.Serialization? So far I have this:

namespace boost {
    namespace serialization {
        template<class Archive, class T>
        void save(Archive& ar, QSharedPointer<T> const& ptr, unsigned version) {
            T* sharedPointer = ptr.data();
            ar & BOOST_SERIALIZATION_NVP(sharedPointer);
        }

        template<class Archive, class T>
        void load(Archive& ar, QSharedPointer<T>& ptr, unsigned version) {
            T* sharedPointer = 0;
            ar & BOOST_SERIALIZATION_NVP(sharedPointer);
            ptr = QSharedPointer<T>(sharedPointer);
        }

        template<class Archive, class T>
        void save(Archive& ar, QWeakPointer<T> const& ptr, unsigned version) {
            T* weakPointer = ptr.toStrongRef().data();
            ar & BOOST_SERIALIZATION_NVP(weakPointer);
        }

        template<class Archive, class T>
        void load(Archive& ar, QWeakPointer<T>& ptr, unsigned version) {
            T* weakPointer = 0;
            ar & BOOST_SERIALIZATION_NVP(weakPointer);
            ptr = QSharedPointer<T>(weakPointer);
        }
    }
}

This is not working because the shared pointers are always constructed from raw pointers so they all think the reference count is 1. It also immediately frees weak pointers.

With some effort I can convert the classes to use boost::shared_ptr and boost::weak_ptr. Will that do any good?

+2  A: 

The question is what do you really want to achieve by serializing pointers? What is your expected output? Note that pointers point to a place in memory -- several may point to the same place in memory.

Serializing the address won't work. You can't just write down the exact memory address, because there's no way to guarantee that objects on the next run will be able to take the same space (another program may have already reserved that place).

Serializing the pointed object in each place where we have a pointer wont work:

  1. This would be a lot more data that we'd need to serialize
  2. If we had weak pointers creating a circular dependency we wouldn't be able to stop and retrieve that connection later.
  3. There is no way to merge the same objects into one when deserializing

Now that you think about it, you can try the official answer of boost::serialization:

Kornel Kisielewicz
I think the 2nd solution should work for me, thank you.
stribika