2010-05-18 4 views
4

boost :: serialization을 사용하면 변경 가능한 멤버에 캐시 된 파생 값이 들어있는 객체를 직렬화하는 "최상의"방법은 무엇입니까?변경할 멤버가있는 boost :: serialization

class Example 
{ 
public: 
    Example(float n) : 
     num(n), 
     sqrt_num(-1.0) 
    {} 

    // compute and cache sqrt on first read 
    float get_sqrt() const 
    { 
     if(sqrt_num < 0) 
      sqrt_num = sqrt(num); 
     return sqrt_num; 
    } 

    template <class Archive> 
    void serialize(Archive& ar, unsigned int version) 
    { ... } 
private: 
    float num; 
    mutable float sqrt_num; 
}; 

유지 보수를 위해 serialize()를 별도의 save() 및 load() 메서드로 분리하지 마십시오. 직렬화의

하나의 최적 구현 :

template <class Archive> 
    void serialize(Archive& ar, unsigned int version) 
    { 
     ar & num; 
     sqrt_num = -1.0; 
    } 

이 역 직렬화 케이스를 처리하지만, 직렬화의 경우, 캐시 된 값을 살해하고 다시 계산해야합니다.

이 경우 가장 좋은 방법은 무엇입니까?

답변

2

Archive::is_loading 필드를 확인하고 캐시 된 값이로드되면로드 할 수 있습니다.

template <class Archive> 
void serialize(Archive& ar, unsigned int version) 
{ 
    ar & num; 
    if(Archive::is_loading::value == true) 
     sqrt_num = -1.0; 
} 
+1

와우, 질문을 한 지 3.5 년 후에 답변! –

3

저장 및로드 방법을 분할한다고해서 직렬화 코드 복사본을 두 개 유지해야한다는 의미는 아닙니다. 그들을 분리 한 다음 공통 기능으로 다시 결합 할 수 있습니다.

private: 
    friend class boost::serialization::access; 

    BOOST_SERIALIZATION_SPLIT_MEMBER() 

    template <class Archive> 
    void save(Archive& ar, const unsigned int version) const { 
     const_cast<Example*>(this)->common_serialize(ar, version); 
    } 

    template <class Archive> 
    void load(Archive& ar, const unsigned int version) { 
     common_serialize(ar, version); 
     sqrt_num = -1; 
    } 

    template <class Archive> 
    void common_serialize(Archive& ar, const unsigned int version) { 
     ar & num; 
    } 

아마 const_cast으로 나타났습니다. 이것은이 아이디어에 대한 불행한 경고입니다. serialize 멤버 함수가 저장 작업을 위해 const가 아닌 경우에도 save 멤버 함수는 const 여야합니다. 직렬화하려는 객체가 원래 const로 선언되지 않은 한 위에 표시된 것처럼 멀리 던져도 안전합니다. 설명서 briefly mentions the need to cast for const members; 이것은 비슷합니다.

위의 변경 내용을 적용하면 ex1ex2에 대해 코드가 올바르게 "2"로 인쇄되고 일련 코드의 복사본 하나만 유지하면됩니다. load 코드에는 개체의 내부 캐시를 다시 초기화하는 코드 만 포함되어 있습니다. save 함수는 캐시를 건드리지 않습니다.