C++ Boost - serialization of class containing class-hierarchy objects

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP



C++ Boost - serialization of class containing class-hierarchy objects



I have a class A, which contains the object of class B and I want to serialize it. The problem is, the class C inherits from B, so A can contain an object of either B or C. How can I efficiently implement the serialization with Boost?


A


B


C


B


A


B


C



My attempt is below, but I'm getting the error when trying to serialize A with C object, while with B it works correctly. Do you know, what am I doing wrong?


A


C


B



I've found some information about class-hierarchy objects serialization here, but it requires an explicit registration of the type in text_iarchive, whereas I need it to be registered in the A class because I'm not directly serializing B objects.


text_iarchive


A


B


#include <fstream>
#include <iostream>
#include <vector>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>

class B
friend class boost::serialization::access;

private:
template<class Archive>
void save(Archive & ar, const unsigned int version) const
ar & this->v->size();
for(int i = 0; i < this->v->size(); i++)
ar & (*(this->v))[i];

;

template<class Archive>
void load(Archive & ar, const unsigned int version)
size_t size;
int tmp;
ar & size;

this->v = new std::vector<int>(size);
for(int i = 0; i < size; i++)
ar & tmp;
(*this->v)[i] = tmp;



BOOST_SERIALIZATION_SPLIT_MEMBER()

protected:
std::vector<int>* v;

public:
B();
B(std::vector<int>* v);
virtual void print_vals();
;

B::B()
this->v = nullptr;


B::B(std::vector<int>* v)
this->v = v;


void B::print_vals()
for(auto e : *(this->v))
std::cout << e << std::endl;



class C : public B
friend class boost::serialization::access;
private:
int num2;

template<class Archive>
void serialize(Archive & ar, const unsigned int version)
ar & boost::serialization::base_object<B>(*this);
ar & num2;
;

public:
void print_vals() override
for(auto e : *(this->v))
std::cout << e << std::endl;

std::cout << this->num2 << std::endl;


C();
C(int num2, std::vector<int>* v);

;

C::C()
this->num2 = -1;
this->v = nullptr;


C::C(int num2, std::vector<int> *v)
this->num2 = num2;
this->v = v;


class A
friend class boost::serialization::access;

private:
int num;

B* b_obj;

template<class Archive>
void serialize(Archive & ar, const unsigned int version)
ar & num;
ar & b_obj;
;

public:
A();
A(int num, B* b);

void print_vals();
;

A::A()
this->num = -1;
this->b_obj = nullptr;


A::A(int num, B* b)
this->num = num;
this->b_obj = b;


void A::print_vals()
std::cout << this->num << std::endl;
this->b_obj->print_vals();



int main()
std::vector<int> v1,2,3;

B b = B(&v);

A a(4, &b);
std::cout << "a:" << std::endl;
a.print_vals();

std::ofstream ofs("a.txt");

boost::archive::text_oarchive oa(ofs);
oa << a;
ofs.close();


A a2;
std::ifstream ifs("a.txt");

boost::archive::text_iarchive ia(ifs);
ia >> a2;
ifs.close();

std::cout << "a2:" << std::endl;
a2.print_vals();

C c(2, &v);
A a3(6, &c);
std::cout << "a3:" << std::endl;
a3.print_vals();

std::ofstream ofs2("a3.txt");

boost::archive::text_oarchive oa(ofs2);
oa << a3;
ofs.close();


A a4;
std::ifstream ifs2("a3.txt");

boost::archive::text_iarchive ia(ifs2);
ia >> a4;
ifs.close();

std::cout << "a4:" << std::endl;
a4.print_vals();




a:
4
1
2
3
a2:
4
1
2
3
a3:
6
1
2
3
2
terminate called after throwing an instance of 'boost::archive::archive_exception'
what(): unregistered class - derived class not registered or exported
Signal: SIGABRT (Aborted)





May be solved in stackoverflow.com/questions/4432019/…
– leiyc
Aug 12 at 13:24






@leiyc It's not, the question you posted asks about abstract class, but my B class is instantiable.
– Eenoku
Aug 12 at 13:29


B





how about this? stackoverflow.com/questions/33365093/…
– miradham
Aug 12 at 14:12





@Eenoku, works with the hint of miradham. See coliru.stacked-crooked.com/a/57c0f58270c70571
– leiyc
Aug 12 at 15:01





@miradham Could you, please, write a full answer, so I could accept it?
– Eenoku
Aug 12 at 18:53




1 Answer
1



It turns that you have missed BOOST_CLASS_EXPORTfor derived class, i.e.


BOOST_CLASS_EXPORT


BOOST_CLASS_EXPORT(C)



Boost serialization cannot serialize pointer to derived object correctly without this macro.



You can find full working code here






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

Firebase Auth - with Email and Password - Check user already registered

Dynamically update html content plain JS

How to determine optimal route across keyboard