Die Boost C++ Bibliotheken

Zeiger und Referenzen

Boost.Serialization kann Zeiger und Referenzen serialisieren. Weil ein Zeiger eine Adresse eines Objekts speichert, ergibt allein die Serialisierung dieser Adresse keinen Sinn. Wenn ein Zeiger oder eine Referenz serialisiert wird, wird automatisch das Objekt serialisiert, auf das der Zeiger oder die Referenz verweist.

Beispiel 64.8. Zeiger serialisieren
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <iostream>
#include <sstream>

std::stringstream ss;

class animal
{
public:
  animal() = default;
  animal(int legs) : legs_{legs} {}
  int legs() const { return legs_; }

private:
  friend class boost::serialization::access;

  template <typename Archive>
  void serialize(Archive &ar, const unsigned int version) { ar & legs_; }

  int legs_;
};

void save()
{
  boost::archive::text_oarchive oa{ss};
  animal *a = new animal{4};
  oa << a;
  std::cout << std::hex << a << '\n';
  delete a;
}

void load()
{
  boost::archive::text_iarchive ia{ss};
  animal *a;
  ia >> a;
  std::cout << std::hex << a << '\n';
  std::cout << std::dec << a->legs() << '\n';
  delete a;
}

int main()
{
  save();
  load();
}

Im Beispiel 64.8 wird mit new ein neues Objekt vom Typ animal erstellt und im Zeiger a verankert. Dieser Zeiger – und nicht *a – wird serialisiert. Dabei speichert Boost.Serialization nicht die Adresse des Objekts, die im Zeiger gespeichert ist. Es wird automatisch das Objekt serialisiert, auf das a zeigt.

Beim Laden des Archivs wird a nicht notwendigerweise auf die gleiche Adresse gesetzt. Stattdessen wird automatisch ein neues Objekt erstellt, dessen Adresse in a gespeichert wird. Boost.Serialization garantiert, dass das Objekt dem gleicht, das zuvor serialisiert wurde. Für die Adresse gilt dies nicht.

Da im Zusammenhang mit dynamisch reserviertem Speicher Smartpointer verwendet werden, bietet Boost.Serialization auch für diese eine entsprechende Unterstützung an.

Beispiel 64.9. Smartpointer serialisieren
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/serialization/scoped_ptr.hpp>
#include <boost/scoped_ptr.hpp>
#include <iostream>
#include <sstream>

using namespace boost::archive;

std::stringstream ss;

class animal
{
public:
  animal() = default;
  animal(int legs) : legs_{legs} {}
  int legs() const { return legs_; }

private:
  friend class boost::serialization::access;

  template <typename Archive>
  void serialize(Archive &ar, const unsigned int version) { ar & legs_; }

  int legs_;
};

void save()
{
  text_oarchive oa{ss};
  boost::scoped_ptr<animal> a{new animal{4}};
  oa << a;
}

void load()
{
  text_iarchive ia{ss};
  boost::scoped_ptr<animal> a;
  ia >> a;
  std::cout << a->legs() << '\n';
}

int main()
{
  save();
  load();
}

Im Beispiel 64.9 wird der Smartpointer boost::scoped_ptr verwendet, um ein dynamisch reserviertes Objekt vom Typ animal zu verwalten. Damit ein Zeiger vom Typ boost::scoped_ptr serialisiert werden kann, muss die Headerdatei boost/serialization/scoped_ptr.hpp eingebunden werden.

Für den Fall, dass Sie den Smartpointer boost::shared_ptr serialisieren möchten, müssen Sie die Headerdatei boost/serialization/shared_ptr.hpp verwenden. Diese Headerdatei unterstützt auch die Serialisierung des Smartpointers std::shared_ptr.

Beispiel 64.10 verwendet anstatt eines Zeigers eine Referenz.

Beispiel 64.10. Referenzen serialisieren
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <iostream>
#include <sstream>

using namespace boost::archive;

std::stringstream ss;

class animal
{
public:
  animal() = default;
  animal(int legs) : legs_{legs} {}
  int legs() const { return legs_; }

private:
  friend class boost::serialization::access;

  template <typename Archive>
  void serialize(Archive &ar, const unsigned int version) { ar & legs_; }

  int legs_;
};

void save()
{
  text_oarchive oa{ss};
  animal a{4};
  animal &r = a;
  oa << r;
}

void load()
{
  text_iarchive ia{ss};
  animal a;
  animal &r = a;
  ia >> r;
  std::cout << r.legs() << '\n';
}

int main()
{
  save();
  load();
}

Ähnlich wie bei Zeigern wird auch hier automatisch das referenzierte Objekt serialisiert.