2012-03-13 64 views
0

我有一個類A擁有一個std ::矢量,和一組B類的實例,含有一個指向矢量A.升壓序列化 - 使對象追蹤

現在我想用升壓::序列化來序列化A和B的所有實例,但序列化數據中只有一個A中的數據向量實例存在。

我知道,這個問題可以(也常常應該)通過使用shared_ptr的解決,但這不會在我的具體情況的工作。

將序列化方法看起來像什麼來歸檔這個?

下面是我試過的。對我來說,似乎沒有對象跟蹤完成,或者reset_object_address沒有按照我的想法工作。

#include <assert.h> 
#include <vector> 
#include <sstream> 
#include <boost/archive/binary_oarchive.hpp> 
#include <boost/archive/binary_iarchive.hpp> 
#include <boost/serialization/vector.hpp> 

std::stringstream ss; 

// A wrapper class created to controle the serialization traits 
template< typename T > 
struct vector_wrapper { 
    std::vector<T> v; 
    template<class Archive> 
    void serialize(Archive & ar, const unsigned int version) { 
     ar & v; 
    } 
}; 

namespace boost { 
namespace serialization { 
template<class T> 
struct tracking_level<const vector_wrapper<T> * > 
{ 
    typedef mpl::integral_c_tag tag; 
    typedef mpl::int_<track_always> type; 
    BOOST_STATIC_CONSTANT(
     int, 
     value = tracking_level::type::value 
    ); 
}; 
} // namespace serialization 
} // namespace boost 

struct A { 
    vector_wrapper<unsigned> data; 

    BOOST_SERIALIZATION_SPLIT_MEMBER(); 

    A() {}; 
    A(unsigned i) { data.v.push_back(i); } 

    template<class Archive> 
    void save(Archive & ar, const unsigned int version) const { 
     const vector_wrapper<unsigned> * ptr = &data; 
     ar & ptr; 
     std::cout << "SAVE> data size: " << data.v.size() << " ptr: " << &data << std::endl; 
    } 

    template<class Archive> 
    void load(Archive & ar, const unsigned int version) { 
     const vector_wrapper<unsigned> * ptr = 0; 
     ar & ptr; 

     data = *ptr; 
     ar.reset_object_address(&data, ptr); // does not seem to have any effect 
     std::cout << "LOAD> data size: " << data.v.size() << " ptr: " << &data << std::endl; 

     delete ptr; 
    } 
}; 

struct B { 
    const vector_wrapper<unsigned> * ptr_data; 

    B() : ptr_data(0) { } 
    B(const vector_wrapper<unsigned> * p) : ptr_data(p) { } 

    template<class Archive> 
    void serialize(Archive & ar, const unsigned int version) { 
     ar & ptr_data; 
     std::cout << "SERILIAZE> ptr: " << ptr_data << std::endl; 
    } 
}; 

struct C { 
    A a; 
    B b1; 
    B b2; 
    B b3; 

    C() { } // default constructor 
    C (unsigned i) : // bootstrap constructor 
     a(i), 
     b1(&a.data), 
     b2(&a.data), 
     b3(&a.data) { } 

    template<class Archive> 
    void serialize(Archive & ar, const unsigned int version) { 
     ar & a; 
     ar & b1; 
     ar & b2; 
     ar & b3; 
    } 
}; 

int main(int argc, const char *argv[]) { 
    C c1(7); 
    boost::archive::binary_oarchive o(ss); 
    o << c1; 

    C c2; 
    boost::archive::binary_iarchive i(ss); 
    i >> c2; 

    assert(&c1.a.data == c1.b1.ptr_data); 
    assert(&c1.a.data == c1.b2.ptr_data); 
    assert(&c1.a.data == c1.b3.ptr_data); 

    assert(&c2.a.data == c2.b1.ptr_data); // fails 
    assert(&c2.a.data == c2.b2.ptr_data); // fails 
    assert(&c2.a.data == c2.b3.ptr_data); // fails 

    return 0; 
} 

回答

0

One解決方案是若要更改您的保存和加載方法,來:

template<class Archive> 
void save(Archive & ar, const unsigned int version) const { 
    ar & data; 
    std::cout << "SAVE> data size: " << data.v.size() << " ptr: " << &data << std::endl; 
} 

template<class Archive> 
void load(Archive & ar, const unsigned int version) { 
    ar & data; 
    std::cout << "LOAD> data size: " << data.v.size() << " ptr: " << &data << std::endl; 

} 

即,只需直接系列化你vector_wrapper,而不是指針。解決之後,所有的斷言都會通過。