Как сериализовать общие/слабые указатели?

У меня есть сложная сеть объектов, связанных с QSharedPointers и QWeakPointers. Есть ли простой способ сохранить/загрузить их с помощью Boost.Serialization? Пока у меня это:

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);
        }
    }
}

Это не работает, потому что общие указатели всегда создаются из необработанных указателей, поэтому все они думают, что счетчик ссылок равен 1. Это также немедленно освобождает слабые указатели.

Приложив некоторые усилия, я могу преобразовать классы для использования boost::shared_ptr и boost::weak_ptr. Принесет ли это пользу?


person stribika    schedule 18.12.2009    source источник


Ответы (1)


Вопрос в том, чего вы действительно хотите добиться сериализацией указателей? Каков ваш ожидаемый результат? Обратите внимание, что указатели указывают на место в памяти — несколько указателей могут указывать на одно и то же место в памяти.

Сериализация адреса не будет работать. Вы не можете просто записать точный адрес памяти, потому что нет никакой гарантии, что объекты при следующем запуске смогут занять то же место (это место может быть уже зарезервировано другой программой).

Сериализация указанного объекта в каждом месте, где у нас есть указатель, не будет работать:

  1. Это было бы намного больше данных, которые нам нужно было бы сериализовать
  2. Если бы у нас были слабые указатели, создающие циклическую зависимость, мы не смогли бы остановить и восстановить это соединение позже.
  3. Невозможно объединить одни и те же объекты в один при десериализации

Теперь, когда вы думаете об этом, вы можете попробовать официальный ответ boost::serialization:

person Kornel Kisielewicz    schedule 18.12.2009