2009-12-18 2 views
6

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

ответ

5

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

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

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

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

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

+0

Я думаю, что второе решение должно работать для меня, спасибо. – stribika