I have seen many questions, tutorials, and documentation involving serializing derived classes, and I haven\'t been able to reach a consensus on several issues, including (a
Following @sehe's advice, here are some example uses:
Serialize derived class object, not forwarding to parent
#include
#include
#include
class AbstractPoint
{
public:
virtual ~AbstractPoint(){}
virtual void DoSomething() = 0;
};
class Point : public AbstractPoint
{
public:
Point() = default;
Point(const double data) : mData(data) {}
void DoSomething(){}
template
void serialize(TArchive& archive, const unsigned int version)
{
archive & mData;
}
double mData;
};
int main()
{
Point point(7.4);
std::ofstream outputStream("test.txt");
boost::archive::text_oarchive outputArchive(outputStream);
outputArchive << point;
outputStream.close();
Point pointRead;
std::ifstream inputStream("test.txt");
boost::archive::text_iarchive inputArchive(inputStream);
inputArchive >> pointRead;
std::cout << pointRead.mData << std::endl;
return 0;
}
Serialize derived class object, including (automatic) forwarding to parent:
#include
#include
#include
class AbstractPoint
{
public:
virtual ~AbstractPoint(){}
virtual void DoSomething() = 0;
double mParentData = 3.1;
template
void serialize(TArchive& archive, const unsigned int version)
{
archive & mParentData;
}
};
class Point : public AbstractPoint
{
public:
Point() = default;
Point(const double data) : mData(data) {}
void DoSomething(){}
template
void serialize(TArchive& archive, const unsigned int version)
{
// this is not required, the parent serialize() seems to be called automatically
// archive & boost::serialization::base_object(*this);
archive & mData;
}
double mData;
};
int main()
{
Point point(7.4);
std::ofstream outputStream("test.txt");
boost::archive::text_oarchive outputArchive(outputStream);
outputArchive << point;
outputStream.close();
Point pointRead;
std::ifstream inputStream("test.txt");
boost::archive::text_iarchive inputArchive(inputStream);
inputArchive >> pointRead;
std::cout << pointRead.mParentData << std::endl;
std::cout << pointRead.mData << std::endl;
return 0;
}
Serialize derived class pointer, not forwarding to parent (note nothing changes from the object case)
#include
#include
#include
#include
class AbstractPoint
{
public:
virtual ~AbstractPoint(){}
virtual void DoSomething() = 0;
};
class Point : public AbstractPoint
{
public:
Point() = default;
Point(const double data) : mData(data) {}
void DoSomething(){}
template
void serialize(TArchive& archive, const unsigned int version)
{
archive & mData;
}
double mData;
};
int main()
{
std::shared_ptr point(new Point(7.4));
std::ofstream outputStream("test.txt");
boost::archive::text_oarchive outputArchive(outputStream);
outputArchive << point;
outputStream.close();
std::shared_ptr pointRead;
std::ifstream inputStream("test.txt");
boost::archive::text_iarchive inputArchive(inputStream);
inputArchive >> pointRead;
std::cout << pointRead->mData << std::endl;
return 0;
}
Serialize derived class pointer, forwarding to parent (note nothing changes from the object case)
#include
#include
#include
#include
class AbstractPoint
{
public:
virtual ~AbstractPoint(){}
virtual void DoSomething() = 0;
template
void serialize(TArchive& archive, const unsigned int version)
{
archive & mParentData;
}
double mParentData = 3.1;
};
class Point : public AbstractPoint
{
public:
Point() = default;
Point(const double data) : mData(data) {}
void DoSomething(){}
template
void serialize(TArchive& archive, const unsigned int version)
{
archive & mData;
}
double mData;
};
int main()
{
std::shared_ptr point(new Point(7.4));
std::ofstream outputStream("test.txt");
boost::archive::text_oarchive outputArchive(outputStream);
outputArchive << point;
outputStream.close();
std::shared_ptr pointRead;
std::ifstream inputStream("test.txt");
boost::archive::text_iarchive inputArchive(inputStream);
inputArchive >> pointRead;
std::cout << pointRead->mParentData << std::endl;
std::cout << pointRead->mData << std::endl;
return 0;
}
Serialize base class pointer
(We now have to register the type of the derived class with the archives, as well as use boost::serialization::base_object
)
#include
#include
#include
#include
#include
class AbstractPoint
{
public:
virtual ~AbstractPoint(){}
virtual void DoSomething() = 0;
// This is required if we want to serialize an AbstractPoint pointer
template
void serialize(TArchive& archive, const unsigned int version)
{
// do nothing
}
};
class Point : public AbstractPoint
{
public:
Point() = default;
Point(const double data) : mData(data) {}
void DoSomething(){}
template
void serialize(TArchive& archive, const unsigned int version)
{
// Without this, we get unregistered void cast
archive & boost::serialization::base_object(*this);
archive & mData;
}
double mData;
};
int main()
{
std::shared_ptr point(new Point(7.4));
std::ofstream outputStream("test.txt");
boost::archive::text_oarchive outputArchive(outputStream);
outputArchive.register_type();
outputArchive << point;
outputStream.close();
std::shared_ptr pointRead;
std::ifstream inputStream("test.txt");
boost::archive::text_iarchive inputArchive(inputStream);
inputArchive.register_type();
inputArchive >> pointRead;
std::shared_ptr castedPoint = std::dynamic_pointer_cast(pointRead);
std::cout << castedPoint->mData << std::endl;
return 0;
}