Я пытаюсь сериализовать производные классы из абстрактного класса, и я получаю некоторые (очевидные) ошибки.
Вот код (запускается с использованием g ++ -std = c ++ 17 XXXX. cpp -Wall -larmadillo -lboost_serialization):
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/serialization/assume_abstract.hpp>
#include <boost/serialization/serialization.hpp>
#include <boost/serialization/split_member.hpp>
#include <boost/serialization/export.hpp>
#include <boost/serialization/unique_ptr.hpp>
#include <fstream>
#include <iostream>
#include <memory>
#include <sstream>
#include <vector>
class Car {
public:
//Car() = default;
//virtual double getInfo() = 0;
virtual char const* type() const = 0;
virtual ~Car() = default;
private:
friend class boost::serialization::access;
template <class Archive>
void serialize(Archive& ar, const unsigned int version) {};
};
class Audi : public Car {
public:
char const* type() const override { return "Audi"; }
//double getInfo() override { return 2.2; }
Audi(std::string owner1, int hp1, std::string second_owner1, std::string country1)
{
owner = owner1;
hp = hp1;
second_owner = second_owner1;
country = country1;
}
Audi() = default;
std::string owner;
int hp{};
std::string second_owner;
std::string country;
private:
friend class boost::serialization::access;
template <class Archive>
void serialize(Archive& ar, const unsigned int version) {
ar & boost::serialization::base_object<Car>(*this); //https://theboostcpplibraries.com/boost.serialization-class-hierarchies
ar & owner;
ar & hp;
ar & second_owner;
ar & country;
}
};
BOOST_CLASS_EXPORT(Audi);
BOOST_SERIALIZATION_ASSUME_ABSTRACT(Car); //Tell Boost that Car is abstract
int main() {
std::string str;
{
std::unique_ptr<Car> audi = std::make_unique<Audi>("Wilma", 3, "Rene", "Argentina");
audi->type();
std::stringstream strs;
boost::archive::binary_oarchive ar(strs);
ar& audi;
str = strs.str();
}
{
std::unique_ptr<Car> audi; //= std::make_unique<Audi>();
std::stringstream strs(str);
boost::archive::binary_iarchive ar(strs);
ar& audi;
//dynamic_cast<Audi>(audi); Tried using casting but am unfamiliar with it -- perhaps this is the issue?
std::cout << "audi: hp=" << audi->hp << " owner=" << audi->owner <<"\n";
}
}
, и я получаю ошибки:
audi_seri.cpp: In function ‘int main()’:
audi_seri.cpp:84:36: error: cannot dynamic_cast ‘audi’ (of type ‘class std::unique_ptr<Car>’) to type ‘class Audi’ (target is not pointer or reference)
dynamic_cast<Audi>(audi);
^
audi_seri.cpp:86:47: error: ‘class Car’ has no member named ‘hp’
std::cout << "audi: hp=" << audi->hp << " owner=" << audi->owner <<"\n";
^~
audi_seri.cpp:86:72: error: ‘class Car’ has no member named ‘owner’
std::cout << "audi: hp=" << audi->hp << " owner=" << audi->owner <<"\n";
Теперь я знаю, почему это происходит - у машины нет этих переменных. Но как я могу решить эту проблему, когда решение может работать для многих производных классов, которые могут иметь разных членов? Возможно, чтобы решить эту проблему, я должен использовать кастинг?
Чтобы лучше понять, почему я пытаюсь это сделать. Сначала я хотел использовать void serialize () в Car как виртуальную функцию, но это не работает с шаблонами. И поэтому я пришел к приведенному выше коду с помощью https://theboostcpplibraries.com/boost.serialization-class-hierarchies
Вот старый код с void serialize как виртуальная функция:
class Car {
public:
virtual double getInfo() = 0;
private:
template <typename Archive> //This is the problem I am trying to solve: templates cannot be virtual
virtual void serialize(Archive& ar, unsigned int version) = 0;
};
class Audi : public Car {
public:
char const* type() const override { return "Audi"; }
//double getInfo() override { return 2.2; }
Audi(std::string owner1, int hp1, std::string second_owner1, std::string country1)
{
owner = owner1;
hp = hp1;
second_owner = second_owner1;
country = country1;
}
Audi() = default;
std::string owner;
int hp{};
std::string second_owner;
std::string country;
private:
template <class Archive>
void serialize(Archive& ar, const unsigned int version) {
ar & owner;
ar & hp;
ar & second_owner;
ar & country;
}
};
BOOST_SERIALIZATION_ASSUME_ABSTRACT(Car); //Tell Boost that Car is abstract
int main() {
std::string str;
{
std::unique_ptr<Car> audi = std::make_unique<Audi>("Wilma", 3, "Rene", "Argentina");
std::stringstream strs;
boost::archive::binary_oarchive ar(strs);
ar& audi;
str = strs.str();
}
{
std::unique_ptr<Car> audi; //= std::make_unique<Audi>();
std::stringstream strs(str);
boost::archive::binary_iarchive ar(strs);
ar& audi;
//dynamic_cast<Audi>(audi);
std::cout << "audi: hp=" << audi->hp << audi->hp<< " owner=" << "\n";
}
}