Boost.Serialization將處理指針就好了循環引用,感謝object tracking。 如果通過指針序列化對象,默認情況下使用對象跟蹤。它還附帶一個用於std::vector
的串行器(包括boost/serialization/vector.hpp
)。
Boost.Serialzation將跟蹤序列化對象的地址。 如果遇到已經序列化的地址,它將存儲一個「引用」給對象,而不是再次序列化它。
反序列化時,當它遇到他們(這意味着他們必須是指針,以便地址可以被分配給他們),它會解決這些引用到正確的地址。
的唯一限制是,所引用的對象必須動態地分配(在堆)。只要沒有被另一個引用,就可以序列化堆棧上的一個對象。
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首次遇到作爲指針。當序列化時,僅存儲對b的引用。
A a;
B b;
archive >> a >> b; // crashes when deserializing b!
當反序列化一個,所述b將在矢量進行分配。現在你想恢復已經存在於堆棧上的b。由於您無法爲堆棧中的變量分配新地址,因此會崩潰!
正確:
A* a = new A();
B* b = new B();
a.vec.push_back(b); // OK! this works fine
當反序列化b,升壓只會分配b的地址一個它的載體裏面。
Boost.Serialzation還配備了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 * x = new A(); B * y = new B(); x.b.push_back(y); y.a.push_back(x) 存檔<< a << b; 它仍然墜毀 A * xx B * yy 存檔>> * xx >> * yy; 我認爲這與循環引用有關。如果我使用shared_ptr,那麼沒有問題。 – user1397974
@ user1397974如果這不是拼寫錯誤,它會崩潰,因爲您在反序列化時取消引用指針(基於您評論中的代碼)。使用'archive >> xx >> yy;'來代替。 –
是的,你是對的。有用。非常感謝。 – user1397974