- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我有一段代码,其中定义了以下类:Base
, Derived
, Contaienr
.
Derived
明显继承Base
, 而 Container
包含 Base
的 vector 共享指针,可以是 Base
的指针和 Derived
.
我要连载Container
所以 vector 的元素被序列化为 Base
和 Derived
尊敬的,但它似乎不起作用。
这是我的测试代码:
#include <boost/archive/xml_oarchive.hpp>
#include <boost/archive/xml_iarchive.hpp>
#include <boost/serialization/base_object.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/serialization/shared_ptr.hpp>
#include <boost/serialization/string.hpp>
#include <boost/serialization/export.hpp>
#include <iostream>
#include <string>
#include <vector>
#include <memory>
#include <sstream>
/// Base class ///
class Base {
public:
using Ptr = std::shared_ptr<Base>;
public:
void setDouble(double d) {
m_d = d;
}
void setInteger(int c) {
m_c = c;
}
double getDouble() const {
return m_d;
}
int getInteger() const {
return m_c;
}
private:
double m_d;
int m_c;
};
/// Derived class from Base ///
class Derived : public Base {
public:
using Ptr = std::shared_ptr<Derived>;
public:
void setString(const std::string& s) {
m_s = s;
}
const std::string& getString() const {
return m_s;
}
private:
std::string m_s;
};
/// Container of base class pointers ///
class Container {
public:
void addData(Base::Ptr data) {
m_data.push_back(data);
}
const std::vector<Base::Ptr>& getDataVector() const {
return m_data;
}
private:
std::vector<Base::Ptr> m_data;
};
BOOST_SERIALIZATION_SPLIT_FREE(Base)
BOOST_SERIALIZATION_SPLIT_FREE(Derived)
BOOST_SERIALIZATION_SPLIT_FREE(Container)
BOOST_CLASS_EXPORT_GUID(Derived, "Derived")
namespace boost {
namespace serialization {
/// Serialization of base class ///
template<class Archive>
void save(Archive& ar, const Base& m, unsigned int) {
auto d = m.getDouble();
auto i = m.getInteger();
ar& make_nvp("doublevalue", d);
ar& make_nvp("intvalue", i);
}
template<class Archive>
void load(Archive& ar, Base& m, unsigned int) {
double d;
int i;
ar& make_nvp("doublevalue", d);
ar& make_nvp("intvalue", i);
m.setDouble(d);
m.setInteger(i);
}
/// serialization of derived class ///
template<class Archive>
void save(Archive& ar, const Derived& m, unsigned int) {
ar& make_nvp("base", base_object<const Base>(m));
ar& make_nvp("stringvalue", m.getString());
}
template<class Archive>
void load(Archive& ar, Derived& m, unsigned int) {
std::string s;
ar& make_nvp("base", base_object<Base>(m));
ar& make_nvp("stringvalue", s);
m.setString(s);
}
/// serialization of container class ///
template<class Archive>
void save(Archive& ar, const Container& m, unsigned int) {
ar& make_nvp("data", m.getDataVector());
}
template<class Archive>
void load(Archive& ar, Container& m, unsigned int) {
std::vector<Base::Ptr> data;
ar& make_nvp("data", data);
for (const auto& it : data) {
m.addData(it);
}
}
}
} // namespace boost::serialization
int main(int argc, char *argv[]) {
// Initialize container
Container container;
auto baseObj = std::make_shared<Base>();
baseObj->setDouble(4.3);
baseObj->setInteger(6);
auto derivedObj = std::make_shared<Derived>();
derivedObj->setDouble(1.1);
derivedObj->setInteger(2);
derivedObj->setString("string in derived");
container.addData(baseObj);
container.addData(derivedObj);
// Print serialization of Base
std::stringstream basess;
boost::archive::xml_oarchive baseoa{basess};
baseoa << boost::serialization::make_nvp("baseclass", baseObj);
std::cout << basess.str() << std::endl;
// Print serialization of Derived
std::stringstream derivedss;
boost::archive::xml_oarchive derivedoa{derivedss};
derivedoa << boost::serialization::make_nvp("derivedclass", derivedObj);
std::cout << derivedss.str() << std::endl;
// Print serialization of Container
std::stringstream containerss;
boost::archive::xml_oarchive containeroa{containerss};
containeroa << boost::serialization::make_nvp("containerclass", container);
std::cout << containerss.str() << std::endl;
return 0;
}
当我运行程序时,我打印了 baseObj
的序列化那是 Base
的共享指针:
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE boost_serialization>
<boost_serialization signature="serialization::archive" version="17">
<baseclass class_id="0" tracking_level="0" version="1">
<px class_id="1" tracking_level="1" version="0" object_id="_0">
<doublevalue>4.29999999999999982e+00</doublevalue>
<intvalue>6</intvalue>
</px>
</baseclass>
这似乎是正确的,因为我同时拥有 doublevalue
和 intvalue
在基类中定义。
然后我打印 derivedObj
的序列化那是 Derived
的共享指针:
<!DOCTYPE boost_serialization>
<boost_serialization signature="serialization::archive" version="17">
<derivedclass class_id="0" tracking_level="0" version="1">
<px class_id="1" tracking_level="1" version="0" object_id="_0">
<base class_id="2" tracking_level="1" version="0" object_id="_1">
<doublevalue>1.10000000000000009e+00</doublevalue>
<intvalue>2</intvalue>
</base>
<stringvalue>string in derived</stringvalue>
</px>
</derivedclass>
它似乎按预期工作,因为我有基类数据,还有 stringvalue
派生类的。
现在,如果我将两个指针都放入 std::vector<std::shared_ptr<Base>>
在 Container
, 我期待同时序列化 baseObj
和 derivedObj
正确。相反,这是输出:
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE boost_serialization>
<boost_serialization signature="serialization::archive" version="17">
<containerclass class_id="0" tracking_level="0" version="0">
<data class_id="1" tracking_level="0" version="0">
<count>2</count>
<item_version>1</item_version>
<item class_id="2" tracking_level="0" version="1">
<px class_id="3" tracking_level="1" version="0" object_id="_0">
<doublevalue>4.29999999999999982e+00</doublevalue>
<intvalue>6</intvalue>
</px>
</item>
<item>
<px class_id_reference="3" object_id="_1">
<doublevalue>1.10000000000000009e+00</doublevalue>
<intvalue>2</intvalue>
</px>
</item>
</data>
</containerclass>
vector 的两个元素都序列化为 Base
指针。
我尝试使用 BOOST_CLASS_EXPORT_GUID(Derived, "Derived")
文档中建议的宏,但它似乎不起作用。
我还尝试了 this post 中提出的解决方案, 通过评论 BOOST_CLASS_EXPORT_GUID(Derived, "Derived")
并使用 register_type
在Container
的连载中,但问题依然存在:
/// serialization of container class ///
template<class Archive>
void save(Archive& ar, const Container& m, unsigned int) {
ar.template register_type<Derived>();
ar& make_nvp("data", m.getDataVector());
}
template<class Archive>
void load(Archive& ar, Container& m, unsigned int) {
ar.template register_type<Derived>() ;
std::vector<Base::Ptr> data;
ar& make_nvp("data", data);
for (const auto& it : data) {
m.addData(it);
}
}
如何正确序列化 Derived
类存储在 Base
的共享指针 vector 中?
最佳答案
在派生类的情况下,部分问题可能是 std::shared_ptr
的行为。因此,您有必要将 std::shared_ptr
替换为普通指针。
struct A
{
};
struct B : public A
{
};
void fun(const std::shared_ptr<A>& base)
{
std::cout << typeid(base).name() << std::endl;
}
int main(int argc, char *argv[]) {
auto a=std::make_shared<A>();
auto b=std::make_shared<B>();
std::cout << typeid(a).name() << std::endl;
std::cout << typeid(b).name() << std::endl;
fun(a);
fun(b);
}
这给了你,你可能认为第二行和第四行是相等的:
class std::shared_ptr<struct A>
class std::shared_ptr<struct B>
class std::shared_ptr<struct A>
class std::shared_ptr<struct A>
第二个但不是很明显的一点是,你的基类应该至少包含一个 virtual function .您可以通过仅包含以下内容使析构函数成为虚函数:
virtual ~Base() {};
文档说:
It turns out that the kind of object serialized depends upon whether the base class (base in this case) is polymophic or not. If base is not polymorphic, that is if it has no virtual functions, then an object of the type base will be serialized. Information in any derived classes will be lost. If this is what is desired (it usually isn't) then no other effort is required.
在我用普通指针替换所有 shared_ptr
并添加虚拟析构函数后,结果如我所愿,我获得了最后一部分的以下输出:
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE boost_serialization>
<boost_serialization signature="serialization::archive" version="17">
<containerclass class_id="0" tracking_level="0" version="0">
<data class_id="1" tracking_level="0" version="0">
<count>2</count>
<item_version>0</item_version>
<item class_id="2" tracking_level="1" version="0" object_id="_0">
<doublevalue>4.29999999999999982e+00</doublevalue>
<intvalue>6</intvalue>
</item>
<item class_id="3" class_name="Derived" tracking_level="1" version="0" object_id="_1">
<base object_id="_2">
<doublevalue>1.10000000000000009e+00</doublevalue>
<intvalue>2</intvalue>
</base>
<stringvalue>string in derived</stringvalue>
</item>
</data>
</containerclass>
关于c++ - 使用 boost::serialization 将派生类指针序列化为 vector 的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56984607/
我有这个析构函数,它在运行时产生错误“vector 迭代器不可取消引用”。 gridMatrix 是一个 std::vector * > * > * > * > 我添加了 typename 和 typ
我有一个 vector 的 vector ,比方说 std::vector > my2dArray; 现在我想要一个 vector ,其中包含 my2dArray 中 vector 的大小。手动这看起
假设我有一些 vector :v1、v2、v3 假设我还有一个 vector 来保存这些 vList = {v1, v2, v3} 如果我同步了 (vList),这是否意味着 v1、v2 和 v3 也
我正在创建一个 char 的二维 vector 数组作为类变量,但我在将 vector 添加到 vector 数组中时遇到了麻烦。 我正在使用 C++ 11 标准运行 gcc。 我尝试使用 vecto
如何修改 Vec基于 Vec 中某项的信息没有对向量的不可变和可变引用? 我已尝试创建一个最小示例来演示我的特定问题。在我的真实代码中,Builder struct 已经是其他答案提出的中间结构。具体
这个问题在这里已经有了答案: What is the idiomatic Rust way to copy/clone a vector in a parameterized function? (
在我的程序中,我有一个整数 vector 的 vector 。现在我想从 vector 的 vector 中取出一个 vector 并在另一个 vector 容器中对其进行操作,但是我得到了错误...
我得到一个vector>数据由 OpenCV 提供。由于某些原因(例如偏移/缩放),我需要转换数据 Point至Point2f 。我怎样才能做到这一点? 例如: std::vector > conto
我有一个函数,该函数应使用来自字符串类型的给定 vector vector 中的某些元素初始化来自字符串类型的空 vector vector 。我的语法看起来像这样 std::vector> extr
我得到一个vector>数据由 OpenCV 提供。由于某些原因(例如偏移/缩放),我需要转换数据 Point至Point2f 。我怎样才能做到这一点? 例如: std::vector > conto
这里有很多类似的问题,但我没有真正找到任何可以特别回答我的问题的问题。 我有一个 vector 的 vector 作为类的属性。另一个属性是 bucket_count。我想将 vector 的 vec
如果我像这样创建一个 vector 的 vector : std::vector> myVectorOfVectors; 然后用一些东西填充它: std::vector myVector1; myVe
我正在用 C++ 编写自定义 vector 类。我对这样的代码有疑问: vector vec; vec.push_back(one); vec.push_back(two);
这是我发布的问题 c++ program for reading an unknown size csv file (filled only with floats) with constant (b
vector> a; for (int i=0;i v(i+1); iota(v.begin(),v.end(),1); a.push_back(v); } a.erase(a.beg
也许已经晚了,但我不明白为什么我会得到一个超出此代码范围的 vector 下标: int m = 3; int n = 2; std::vector> path(m, std::vector(n, 0
这个问题真的很奇怪,我似乎找不到任何导致它的原因。 所以这里有一个赋值运算符重载函数,鸟类和哺乳动物都是 vector 。 (下面是类) const Register& Register::opera
我怎么去 std::vector> 只是 std::vector> ?有真正有效的方法吗? 最佳答案 我会做这样的事情: #include #include int main() { //
我正在尝试将这些 vector 中的一些数据写入文本文件。当我运行代码时,它返回运行时错误。 Category、Product、Cart、Customer和Address都是struct 包含每个 g
显然它会因您使用的编译器而异,但我很好奇执行 vector> 时的性能问题与 vector*> ,尤其是在 C++ 中。具体来说: 假设您的外部 vector 已满,您想要开始将元素插入到第一个内部
我是一名优秀的程序员,十分优秀!