I wrote an example program to figure out Boost's serialization library before I implemented it into a project, however, I got some unexplained behavior.
In my example, I had two classes: a generic BaseClass
and a specialized DerivedClass
(analogous to what I plan to use Boost for). BaseClass
only has one member, a string called name
, which defaults to "BaseClass". DerivedClass
publicly inherits BaseClass
, sets name
to something else and has its own unique member, data
.
In the main program, I create a DerivedClass
with data
set to "special cool stuff", and a BaseClass
with name
"regular stuff". I write both of these to a file with boost::archive::text_oarchive
, and read the first object, the DerivedClass
, back twice (recreating the std::ifstream
both times). The first time reading it back, I put it to a BaseClass*
. Calling BaseClass::printData()
(a virtual method that prints the std::typeid
and name
) prints something along the lines of:
--- Storage done, now loading the first object as BaseClass ---
9BaseClass: 0
Next, when I load it as a DerivedClass*
and call DerivedClass::printData()
(which is overridden from BaseClass
to include the member data
in the output) correctly prints:
--- Storage done, now loading the first object as DerivedClass ---
12DerivedClass: DerivedClass AND special cool stuff
Looking in the file I'm writing to, I see this:
22 serialization::archive 15 0 1 0
0 1 0
1 12 DerivedClass 18 special cool stuff 1
2 13 regular stuff
And when I call BaseClass::printData()
on the original, pre-serializing DerivedClass
, I get this:
9BaseClass: DerivedClass
Obviously, the DerivedClass
is being stored correctly. Something about loading it as a BaseClass
to check name
is messing up. I cannot think of why it would give me a std::string
containing 0
.
I'm just starting to learn how to use this library, and most of the similar questions and documentation I've found online have no effect (ie, using BOOST_EXPORT_CLASS
or BOOST_CLASS_TYPE_INFO
, although it could very well be I was using them incorrectly).
Here is my code:
main.cpp
#include <iostream>
#include <fstream>
#include <string>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/serialization/nvp.hpp>
#include "baseclass.h"
#include "derivedclass.h"
int main() {
BaseClass* testBase = new BaseClass("regular stuff");
DerivedClass* testDerivate = new DerivedClass("special cool stuff");
testDerivate->BaseClass::printData();
std::cout << std::endl << " --- " << "Storing objects in the file 'output'..." << " --- " << std::endl;
std::ofstream output("storage");
{
boost::archive::text_oarchive boost_out(output);
boost_out << (testDerivate);
testDerivate->printData();
boost_out << (testBase);
testBase->printData();
}
std::cout << std::endl << " --- " << "Storage done, now loading the first object as BaseClass" << " --- " << std::endl;
{
std::ifstream input("storage");
BaseClass* base;
boost::archive::text_iarchive boost_in(input);
boost_in >> (base);
base->printData();
input.close();
}
std::cout << std::endl << " --- " << "Storage done, now loading the first object as DerivedClass" << " --- " << std::endl;
{
std::ifstream input("storage");
DerivedClass* derive;
boost::archive::text_iarchive boost_in(input);
boost_in >> (derive);
derive->printData();
input.close();
}
return 0;
}
baseclass.h
#pragma once
#include <string>
#include <iostream>
#include <typeinfo>
#include <boost/serialization/access.hpp>
#include <boost/serialization/nvp.hpp>
class BaseClass
{
public:
BaseClass() {
name = "BaseClass";
}
BaseClass(std::string custom) {
name = custom;
}
virtual ~BaseClass() {}
virtual void printData() {
std::cout << typeid(*this).name() << ": " << name << std::endl;
}
protected:
std::string name;
private:
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive & ar, const unsigned int version) {
ar & (name);
}
};
derivedclass.hpp
#pragma once
#include <string>
#include <iostream>
#include <typeinfo>
#include <boost/serialization/base_object.hpp>
#include <boost/serialization/access.hpp>
#include "baseclass.h"
class DerivedClass : public BaseClass
{
public:
DerivedClass() : BaseClass("DerivedClass") {}
DerivedClass(std::string custom) : BaseClass("DerivedClass") {
data = custom;
}
virtual ~DerivedClass() {}
void printData() override {
std::cout << typeid(*this).name() << ": " << name << " AND " << data << std::endl;
}
protected:
std::string data;
private:
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive & ar, const unsigned int version) {
ar & (boost::serialization::base_object<BaseClass>(*this));
ar & (data);
}
};
Sorry if this is a bit long, I wanted to be as descriptive as possible. I'm very new to using Boost and I'm not all that experienced with C++, so even if you just have some general comments on my code, I'd appreciate it.