我有一个需要序列化的树状结构。典型结构,每个节点都有parent
个成员和children
个向量。 parent
是指向类的原始指针,children
是vector
的{{1}}。现在看来序列化工作正常,但 de -serialization使shared_ptr
成员未初始化(指向parent
或0xcccccccc
)。
当实际父对象尚未完成反序列化时,正在加载0x00000000
成员,即通过父parent
的反序列化请求加载子parent
成员。由于这是循环的,我想知道我是否需要采取特殊措施才能发挥作用。
感谢您的帮助。
更新:这是我的序列化功能的样子:
children
如果我发表评论template <typename Archive>
void serialize(Archive& archive, GameCore::GameObject& t, const unsigned int version)
{
archive & boost::serialization::base_object<GameCore::Object>(t);
archive & boost::serialization::base_object<GameCore::Updatable>(t);
archive & t.parent;
archive & t.transform;
archive & t.components;
archive & t.children;
}
,archive & t.children
会正确填充。
更新2:好的,我已成功将其转变为显示问题的最小样本。以下应编译:
parent
逐步完成代码。孩子的#include <boost\archive\binary_oarchive.hpp>
#include <boost\archive\binary_iarchive.hpp>
#include <fstream>
#include <memory>
#include <vector>
class A
{
public:
A() {}
A(const A& rhs) = delete;
int someInt = 0;
A* parent = nullptr;
std::vector<A*> children;
template <class Archive>
void serialize(Archive& archive, const unsigned int version)
{
archive & someInt;
archive & parent;
int count = children.size();
archive & count;
children.resize(count);
for (int i = 0; i < count; ++i)
{
A* ptr = children[i];
archive & ptr;
children[i] = ptr;
}
}
};
int main()
{
A* newA = new A();
newA->someInt = 0;
A* newPtr = new A();
newPtr->someInt = 5;
newPtr->parent = newA;
newA->children.push_back(newPtr);
// Save.
std::ofstream outputFile("test", std::fstream::out | std::fstream::binary);
if (outputFile.is_open())
{
boost::archive::binary_oarchive outputArchive(outputFile);
// Serialize objects.
outputArchive << newA;
outputFile.close();
}
delete newA;
delete newPtr;
A* loadedPtr = nullptr;
// Load.
std::ifstream inputFile("test", std::fstream::binary | std::fstream::in);
if (inputFile && inputFile.good() && inputFile.is_open())
{
boost::archive::binary_iarchive inputArchive(inputFile);
// Load objects.
inputArchive >> loadedPtr;
inputFile.close();
}
return 0;
}
始终为空。
答案 0 :(得分:3)
Visual Studio 2013 / Visual C ++ 12的已知错误
Visual Studio 2013 在发布过程中很晚才发布,所以存在几个 尚未解决的问题。其中包括:
由于缺少include,序列化无法编译。
答案 1 :(得分:1)
我过去遇到了同样的问题,我没有找到开箱即用的可靠解决方案..但是下面的小黑客工作正常 - 你可以单独指定序列化和反序列化功能(不使用默认值)模板和&amp; -operator):
//! Serialization
void A::serialize(xml_oarchive& ar, const unsigned int version)
{
ar << value;
}
//! De-serialization
void A::serialize(xml_iarchive& ar, const unsigned int version)
{
ar >> value;
}
之后,您可以指定在反序列化方法中恢复指向父对象的指针,如下所示:
//! Serialization
void A::serialize(xml_oarchive& ar, const unsigned int version)
{
ar << children;
}
//! De-serialization
void A::serialize(xml_iarchive& ar, const unsigned int version)
{
ar >> children;
for(var child: children)
child->parent = this;
}
答案 2 :(得分:1)
这已在开发分支上解决。
答案 3 :(得分:0)
如果你使用Boost Serialization,一切都应该是开箱即用的。您的类序列化可能看起来像
#include <boost/serialization/vector.hpp>
void serialize (Archive&ar, unsigned int version)
{
//declare possible derived types of nodes
ar & parent;
ar & children;
}
归档将散列指针,因此它不会多次创建每个元素。
一个重要的细节:如果您的节点可以是某种派生类型,您需要教导存档在//位置期望的类型, 通过指向基类型的指针,查看有关序列化派生类型的boost文档中的详细信息。
如果你确定你的树结构是正确的并且是自包含的(root有NULL作为父对象,所有其他节点都是它们各自“父”的“子”等),那么你可以更有效地组织代码:
#include <boost/serialization/vector.hpp>
void serialize (Archive&ar, unsigned int version)
{
//declare possible derived types of nodes (either here or at archive creation point)
ar & children;
if (typename Archive::is_loading())
{
for (auto child : children)
child->parent = this;
}
}
(我假设你在构造函数中将“parent”设置为NULL)。
我没有使用VS 2013测试此代码。