Я пытаюсь выучить boost :: serialization для создания одинаковой игровой системы, и я довольно далеко продвинулся в формате text_oarchive. Я узнал, как использовать BOOST_CLASS_EXPORT_GUID для полиморфных классов и использовать BOOST_SERIALIZATION_NVP для XML-архивов. Затем, когда я попытался объединить их, используя полиморфные классы с форматом архива xml_oarchive, я получил ошибку во время выполнения.
Ошибка:
Мой код:
#include <fstream>
#include <boost/serialization/serialization.hpp>
#include <boost/archive/xml_oarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/serialization/export.hpp>
struct base {
friend class boost::serialization::access;
//...
// only required when using method 1 below
// no real serialization required - specify a vestigial one
template<class Archive>
void serialize(Archive & ar, const unsigned int file_version){}
virtual ~base() { }
};
struct derived : public base {
friend class boost::serialization::access;
int i = 93894;template<class Archive>
void serialize(Archive & ar, const unsigned int file_version){
// method 1 : invoke base class serialization
ar & BOOST_SERIALIZATION_NVP(boost::serialization::base_object<base>(*this));
ar & BOOST_SERIALIZATION_NVP(i);
}
virtual ~derived() { }
};
BOOST_CLASS_EXPORT_GUID(derived, "derived")int main()
{
std::ofstream ofstr("file.txt");
boost::archive::xml_oarchive oarch(ofstr);
base* b = new derived();
oarch << BOOST_SERIALIZATION_NVP(b);
std::cin.get();
delete b;
}
Все это прекрасно работает с форматом text_oarchive, но когда я изменяю его на xml_oarchive, происходит сбой.
Что я делаю здесь не так, кажется, я сделал все, что мне сказали учебники.
Хорошо, я нашел проблему. Это не имело никакого отношения к полиморфизму вообще.
Проблема была с этой линией
ar & BOOST_SERIALIZATION_NVP(boost::serialization::base_object<base>(*this));
Проблема в том, что boost::serialization::base_object<base>(*this)
не имеет имени переменной, которое используется для разрешения имени тега XML. Когда я изменил точно такой же код:
ar & boost::serialization::make_nvp("owner", boost::serialization::base_object<base>(*this));
Который явно делает nvp, используя метод make_nvp. Таким образом, ему дается имя, а не пытаться понять его по имени, которого не существует.