C++ 如何使用boost序列化具有共享\u ptr成员的对象
有抽象的C++ 如何使用boost序列化具有共享\u ptr成员的对象,c++,serialization,boost,deserialization,C++,Serialization,Boost,Deserialization,有抽象的I1和派生的C1 有抽象的I2和派生的C2 I1拥有共享\u ptr。如何使用boost serializaton使它们可序列化?我正在尝试这样做,但我的应用程序出现异常 #include <sstream> #include <boost/shared_ptr.hpp> #include <boost/archive/binary_oarchive.hpp> #include <boost/archive/binary_iarchive.hpp
I1
和派生的C1
有抽象的I2
和派生的C2
I1
拥有共享\u ptr
。如何使用boost serializaton使它们可序列化?我正在尝试这样做,但我的应用程序出现异常
#include <sstream>
#include <boost/shared_ptr.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/serialization/shared_ptr.hpp>
struct I1
{
I1() {}
virtual ~I1() = 0 {}
template<class Archive>
void serialize(Archive &ar, const unsigned int version)
{
}
};
struct C1 : I1
{
virtual ~C1() {}
template<class Archive>
void serialize(Archive &ar, const unsigned int version)
{
ar & boost::serialization::base_object<I1>(*this);
}
};
struct I2
{
virtual ~I2() = 0 {}
template<class Archive>
void serialize(Archive &ar, const unsigned int version)
{
ar & p;
}
boost::shared_ptr<I1> p;
};
struct C2 : I2
{
C2() { p = boost::shared_ptr<I1>(new C1); }
virtual ~C2() { }
template<class Archive>
void serialize(Archive &ar, const unsigned int version)
{
ar & boost::serialization::base_object<I2>(*this);
}
};
int main()
{
C2 c2;
std::string s;
std::stringstream ss(s);
boost::archive::binary_oarchive oa(ss);
oa.register_type<I1>();
oa.register_type<C1>();
oa.register_type<I2>();
oa.register_type<C2>();
oa << c2;
boost::archive::binary_iarchive ia(ss);
//ia.register_type<I1>(); // cannot instantiate abstract class
ia.register_type<C1>();
//ia.register_type<I2>(); // cannot instantiate abstract class
ia.register_type<C2>();
ia >> c2;
}
#包括
#包括
#包括
#包括
#包括
结构I1
{
I1(){}
虚拟~I1()=0{}
模板
无效序列化(存档和ar,常量未签名整数版本)
{
}
};
结构C1:I1
{
虚拟~C1(){}
模板
无效序列化(存档和ar,常量未签名整数版本)
{
ar&boost::serialization::base_对象(*this);
}
};
结构I2
{
虚拟~I2()=0{}
模板
无效序列化(存档和ar,常量未签名整数版本)
{
ar&p;
}
boost::共享\u ptr p;
};
结构C2:I2
{
C2(){p=boost::shared_ptr(新C1);}
虚拟~C2(){}
模板
无效序列化(存档和ar,常量未签名整数版本)
{
ar&boost::serialization::base_对象(*this);
}
};
int main()
{
C2;
std::字符串s;
标准::stringstream ss(s);
boost::archive::binary_oarchive oa(ss);
oa.register_type();
oa.register_type();
oa.register_type();
oa.register_type();
oa>c2;
}
添加
根据文件
更新
我刚刚用VS2013RTM和Boost 1_55进行了验证,它可以正常工作(TM),我已经
- 删除了抽象基的类型注册(无论如何都不能从存档中具体加载)
- 增加
#pragma warning(disable: 4244) #include <boost/config/warning_disable.hpp>
在文件顶部,以使已知的闲聊警告静音#杂注警告(禁用:4244) #包括
- 通过指针序列化c2(堆栈变量可以)
#pragma warning(disable: 4244)
#include <boost/config/warning_disable.hpp>
#include <sstream>
#include <boost/shared_ptr.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/serialization/shared_ptr.hpp>
struct I1
{
I1() {}
virtual ~I1() = 0 {}
template<class Archive>
void serialize(Archive &ar, const unsigned int version)
{
}
};
struct C1 : I1
{
virtual ~C1() {}
template<class Archive>
void serialize(Archive &ar, const unsigned int version)
{
ar & boost::serialization::base_object<I1>(*this);
}
};
struct I2
{
virtual ~I2() = 0 {}
template<class Archive>
void serialize(Archive &ar, const unsigned int version)
{
ar & p;
}
boost::shared_ptr<I1> p;
};
struct C2 : I2
{
C2() { p = boost::shared_ptr<I1>(new C1); }
virtual ~C2() { }
template<class Archive>
void serialize(Archive &ar, const unsigned int version)
{
ar & boost::serialization::base_object<I2>(*this);
}
};
int main()
{
boost::shared_ptr<I2> c2(new C2);
std::string s;
std::stringstream ss(s);
boost::archive::text_oarchive oa(ss);
oa.register_type<C1>();
oa.register_type<C2>();
oa << c2;
std::cout << "Serialized form: '" << ss.str() << "'\n";
boost::archive::text_iarchive ia(ss);
ia.register_type<C1>();
ia.register_type<C2>();
ia >> c2;
}
#杂注警告(禁用:4244)
#包括
#包括
#包括
#包括
#包括
#包括
结构I1
{
I1(){}
虚拟~I1()=0{}
模板
无效序列化(存档和ar,常量未签名整数版本)
{
}
};
结构C1:I1
{
虚拟~C1(){}
模板
无效序列化(存档和ar,常量未签名整数版本)
{
ar&boost::serialization::base_对象(*this);
}
};
结构I2
{
虚拟~I2()=0{}
模板
无效序列化(存档和ar,常量未签名整数版本)
{
ar&p;
}
boost::共享\u ptr p;
};
结构C2:I2
{
C2(){p=boost::shared_ptr(新C1);}
虚拟~C2(){}
模板
无效序列化(存档和ar,常量未签名整数版本)
{
ar&boost::serialization::base_对象(*this);
}
};
int main()
{
boost::共享ptr c2(新c2);
std::字符串s;
标准::stringstream ss(s);
boost::archive::text\u oarchive oa(ss);
oa.register_type();
oa.register_type();
oa我认为您也不应该在输出归档上注册纯虚拟类
或者,您可以使用。定义类后,用以下代码替换其余代码:
#include <boost/serialization/export.hpp>
BOOST_CLASS_EXPORT(C1)
BOOST_CLASS_EXPORT(C2)
int main()
{
C2 c2;
std::string s;
std::stringstream ss(s);
{
boost::archive::binary_oarchive oa(ss);
oa << c2;
}
boost::archive::binary_iarchive ia(ss);
ia >> c2;
}
#包括
增压级出口(C1)
增压级输出(C2)
int main()
{
C2;
std::字符串s;
标准::stringstream ss(s);
{
boost::archive::binary_oarchive oa(ss);
oa>c2;
}
我将输出存档放在一个单独的块中。我认为它很可能在没有它的情况下工作,但我希望确保所有内容都已刷新(通过超出范围)。boost序列化文档介绍了有关boost\u CLASS\u导出的有趣内容:
…促进一流的出口
因此,导出的需要通过使用派生类来暗示,派生类通过指向其基类的指针或引用进行操作
您的p
指针正是这样做的。将这些宏添加到您的代码中还可以摆脱来自main的难看的显式register\u type()
调用,这也很好:)
因此,这段代码似乎在VS2014中编译并运行:
#include <sstream>
#include <boost/shared_ptr.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/serialization/shared_ptr.hpp>
#include <boost/serialization/export.hpp>
struct I1
{
I1() {}
virtual ~I1() = 0 {}
template<class Archive>
void serialize(Archive &ar, const unsigned int version)
{
}
};
BOOST_CLASS_EXPORT(I1)
struct C1 : I1
{
virtual ~C1() {}
template<class Archive>
void serialize(Archive &ar, const unsigned int version)
{
ar & boost::serialization::base_object<I1>(*this);
}
};
BOOST_CLASS_EXPORT(C1)
struct I2
{
virtual ~I2() = 0 {}
template<class Archive>
void serialize(Archive &ar, const unsigned int version)
{
ar & p;
}
boost::shared_ptr<I1> p;
};
BOOST_CLASS_EXPORT(I2)
struct C2 : I2
{
C2() { p = boost::shared_ptr<I1>(new C1); }
virtual ~C2() { }
template<class Archive>
void serialize(Archive &ar, const unsigned int version)
{
ar & boost::serialization::base_object<I2>(*this);
}
};
BOOST_CLASS_EXPORT(C2)
int main()
{
C2 c2;
std::string s;
std::stringstream ss(s);
boost::archive::binary_oarchive oa(ss);
oa << c2;
boost::archive::binary_iarchive ia(ss);
ia >> c2;
}
#包括
#包括
#包括
#包括
#包括
#包括
结构I1
{
I1(){}
虚拟~I1()=0{}
模板
无效序列化(存档和ar,常量未签名整数版本)
{
}
};
增压级输出(I1)
结构C1:I1
{
虚拟~C1(){}
模板
无效序列化(存档和ar,常量未签名整数版本)
{
ar&boost::serialization::base_对象(*this);
}
};
增压级出口(C1)
结构I2
{
虚拟~I2()=0{}
模板
无效序列化(存档和ar,常量未签名整数版本)
{
ar&p;
}
boost::共享\u ptr p;
};
增压级输出(I2)
结构C2:I2
{
C2(){p=boost::shared_ptr(新C1);}
虚拟~C2(){}
模板
无效序列化(存档和ar,常量未签名整数版本)
{
ar&boost::serialization::base_对象(*this);
}
};
增压级输出(C2)
int main()
{
C2;
std::字符串s;
标准::stringstream ss(s);
boost::archive::binary_oarchive oa(ss);
oa>c2;
}
不过,有趣的是,Boost docs的声明显然不适用于所有编译器,而且互联网上的许多代码示例在VS2014中都不起作用。它们需要添加到哪里?我会在接口声明之后立即添加它们classes@Ufx不管它值多少钱,我现在已经在VS2013上对它进行了测试-I didn在其他时间无法访问Windows。也许您应该在一个独立的、新的控制台应用程序中尝试它,以排除项目/生成设置的其余部分出现问题。我刚刚替换了除主函数(和标题)之外的所有函数它仍然崩溃。martin_pr的solusion没有崩溃。你能告诉我们哪个编译器接受=0{}
语法吗?我知道它存在,但我不知道有哪个编译器能够足够有趣地接受这种输入,你的代码在Linu上的gcc 4.8.1上运行良好
#include <sstream>
#include <boost/shared_ptr.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/serialization/shared_ptr.hpp>
#include <boost/serialization/export.hpp>
struct I1
{
I1() {}
virtual ~I1() = 0 {}
template<class Archive>
void serialize(Archive &ar, const unsigned int version)
{
}
};
BOOST_CLASS_EXPORT(I1)
struct C1 : I1
{
virtual ~C1() {}
template<class Archive>
void serialize(Archive &ar, const unsigned int version)
{
ar & boost::serialization::base_object<I1>(*this);
}
};
BOOST_CLASS_EXPORT(C1)
struct I2
{
virtual ~I2() = 0 {}
template<class Archive>
void serialize(Archive &ar, const unsigned int version)
{
ar & p;
}
boost::shared_ptr<I1> p;
};
BOOST_CLASS_EXPORT(I2)
struct C2 : I2
{
C2() { p = boost::shared_ptr<I1>(new C1); }
virtual ~C2() { }
template<class Archive>
void serialize(Archive &ar, const unsigned int version)
{
ar & boost::serialization::base_object<I2>(*this);
}
};
BOOST_CLASS_EXPORT(C2)
int main()
{
C2 c2;
std::string s;
std::stringstream ss(s);
boost::archive::binary_oarchive oa(ss);
oa << c2;
boost::archive::binary_iarchive ia(ss);
ia >> c2;
}