c++ boost序列化类之间相互引用
c++ boost serialization class refer to each other
我是c++ boost的新手,所以这个问题可能是基本的:如何序列化两个用指针相互引用的类。例如:
class A;
class B;
class A {
public:
...
private:
double a;
vector <B*> b;
}
class B {
public:
...
private:
int b;
list <A*> a;
}
类A有一个包含指针B*的私有向量,而类B有一个包含指针A*的私有列表。
特别是通过反序列化会有问题(指针!)。有人知道吗?
由于对象跟踪,序列化可以很好地处理指针的循环引用。如果通过指针序列化对象,则默认使用对象跟踪。它还附带了std::vector
的序列化器(包括boost/serialization/vector.hpp
)。
提振。序列化将跟踪您序列化的对象的地址。如果遇到一个已经序列化的地址,它将存储一个对该对象的"引用",而不是再次序列化它。
在反序列化时,它将在遇到这些引用时将其解析为正确的地址(这意味着它们必须是指针,以便可以为它们分配地址)。
唯一的限制是,被引用的对象必须动态地(在堆上)分配。你可以在堆栈上序列化一个对象,只要它不被另一个对象引用。
A a;
B b;
a.vec.push_back( &b ); // WRONG! deserialization will crash
// if a does not reference to b, it will work
archive << a << b;
这样做的原因是:b在序列化a(在其vector中)时首先作为指针遇到。序列化b本身时,只存储对b的引用。
A a;
B b;
archive >> a >> b; // crashes when deserializing b!
当反序列化a时,将在vector中分配b。现在您想要恢复b,它已经存在于堆栈中。因为你不能给堆栈上的变量赋一个新地址,它会崩溃!
正确的:
A* a = new A();
B* b = new B();
a.vec.push_back(b); // OK! this works fine
当对b进行反序列化时,boost只会将a向量内的b的地址赋值给它。
提振。序列化还附带了boost::shared_ptr
(包括boost/serialization/shared_ptr.hpp
)的序列化器,这可能使您的任务更容易使用std::vector< boost::shared_ptr<A> >
代替,这样你就不必担心释放内存。
了解了基础知识之后,您就可以像下面这样简单地实现类的序列化:
// add this to your classes you want to serialize
private:
friend boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, unsigned version) {
//TODO: serialize other member variables
ar & BOOST_SERIALIZATION_NVP(vec); // vec is a std::vector
}
如果您选择使用shared_ptrs向量(只包括头部),则不需要更改
基本思想是避免循环引用,因为您的序列化将产生一个无限循环。
根据本教程,A和B实例之间的非循环引用不应该有任何问题
- 常量引用和引用之间的区别
- C++ 对非常量对象的常量引用和对非常量对象的非常量引用之间的区别
- 左值引用和右值引用之间的区别
- DLL 引用之间的区别?和用途?
- C++中的变量和引用之间的区别是什么
- 句柄、指针和引用之间有什么区别
- 未定义的引用-"a=-b;"之间是否存在差异和`a=-1*b;`和C++中的"a=0-b&
- 返回类型中 && 和没有引用之间的区别
- 如何在函数参数中的右值和右值引用之间进行区分
- 模板中的右值引用和常量左值引用之间的重载
- 作为自变量的右值引用和左值引用之间的差异
- c++中指针和引用之间的区别
- “迭代器”和“对元素的引用”之间的区别
- 基元引用之间的static_cast
- Go和C++中指针和引用之间的逻辑差异
- 引用和左值引用之间有什么区别吗
- 指针 (*) 和引用 (&) 之间的区别
- Lua注册表与轻用户数据和引用之间的区别是什么?
- 数组指针与数组引用之间的差异
- 在指针和引用之间进行转换