Как сериализовать общие / слабые указатели? - PullRequest
6 голосов
/ 18 декабря 2009

У меня сложная сеть объектов, связанных с 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. Это принесет пользу?

1 Ответ

5 голосов
/ 18 декабря 2009

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

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

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

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

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

...