2016-08-25 7 views
-1

여러 소스에서 가져올 수있는 객체 (예 : 소스 1과 소스 2)의 직렬화를 구성하려고하는데 스키마 처리가 모두 엉망입니다. 그래서 나는 부드러운 직렬화를 다루려고 노력하고있다.다중 소스 및 다른 스키마에서 객체를 직렬화하는 매끄러운 방법?

void CSerFoo::Serialize(CArchive& ar) 
{ 
    try 
    { 
     //ar.Flush(); 
     SerializeEx(ar); // For the Serialization of the Good Ones, from the point now on 
    } 
    catch(...) // If the Object cannot be Serialized using the above Method try the Next way to decode 
    { 
     try 
     { 
      //ar.Flush(); 
      SpecialSerialize1(ar); // For the Serialization of the Objects from the Source 1, actually code from the Source 1 
     } 
     catch(...) // If the Object cannot be Serialized using the above Method try the Last way to decode 
     { 
      try 
      { 
       //ar.Flush(); 
       SpecialSerialize2(ar); // For the Serialization of the Objects from the Source 2, actually code from the Source 2 
      } 
      catch(...) 
      { 
       // No way 
      } 
     } 
    } 
} 

편집 1 :

이 소스에서 직렬화 코드 1

// From Source 1 
IMPLEMENT_SERIAL(CSerFoo, CObject, VERSIONABLE_SCHEMA | 3) 
void CSerFoo::Serialize(CArchive& ar) // This will be the Consolidated CSerFoo's SpecialSerialize1 
{ 
    UINT uiSchema = ar.GetObjectSchema(); 
    if (ar.IsStoring()) 
    { 
     ar << m_sName;       
     ar << m_sDesc; 
     ar << m_String1; 

     ar << m_fValue1; 
     ar << m_fValue2; 

     ar << m_iValue1; 
     ar << m_iValue2; 

     ar << m_String2; 
     ar << m_String3; 

    } 
    else 
    { 
     ar >> m_sName;       
     ar >> m_sDesc; 
     ar >> m_String1; 

     if(uischema > 0)// Added in VERSION_SCHEMA 1 
     { 
      ar >> m_fValue1; 
      ar >> m_fValue2; 
     } 

     if(uischema > 1) // Added in VERSION_SCHEMA 2 
     { 
      ar >> m_iValue1; 
      ar >> m_iValue2; 
      ar >> m_String4; 
     } 

     if(uischema > 2) // Added in VERSION_SCHEMA 3 
     { 
      ar >> m_String2; 
      ar >> m_String3; 
     } 
    } 
} 

이것은 직렬화 코드 소스에서 지금이

// From Source 2 
IMPLEMENT_SERIAL(CSerFoo, CObject, VERSIONABLE_SCHEMA | 3) 
void CSerFoo::Serialize(CArchive& ar) // This will be the Consolidated CSerFoo's SpecialSerialize2 
{ 
    UINT uiSchema = ar.GetObjectSchema(); 
    if (ar.IsStoring()) 
    { 
     ar << m_sName;       
     ar << m_sDesc; 
     ar << m_String1; 

     ar << m_fValue1; 

     ar << m_fValue2; 
     ar << m_iValue1; 
     ar << m_iValue2; 

     ar << m_iValue3; 
     ar << m_String2; 
     ar << m_String3; 

    } 
    else 
    { 
     ar >> m_sName;       
     ar >> m_sDesc; 
     ar >> m_String1; 

     if(uischema > 0)// Added in VERSION_SCHEMA 1 
     { 
      ar >> m_fValue1; 

     } 

     if(uischema > 1) // Added in VERSION_SCHEMA 2 
     { 
      ar >> m_fValue2; 
      ar >> m_iValue1; 
      ar >> m_iValue2; 
     } 

     if(uischema > 2) // Added in VERSION_SCHEMA 3 
     { 
      ar >> m_iValue3; 
      ar >> m_String2; 
      ar >> m_String3; 
     } 
    } 
    // m_String4 is not there in the Source 2 
} 

통합 CSerFoo (에서 지금) 양쪽 출처에서 모든 들판을 가지고있다. 그리고 거기에서 우리는 ne wer CSerFoo의 동일한 객체에 대한 직렬화. 우리는 다른 수업을 만드는 것에 타협 할 수 없습니다.

문제는 내가 직면 한 문제입니다. 직렬화의 후속 호출에서 커서 (CArchive :: m_lpBufCur)가 이동되어 다음 번에 Serialize가 실패합니다.

이 방법이 있습니까?

나는 무엇이 있습니까?

미리 감사드립니다.

+1

SerializeEx 및 SpecialSerializeX의 기능을 알지 못하면이 문제에 관해 말할 내용이 없습니다. –

+0

이것은 모두 int, float 및 string을 순차적으로 직렬화 한 것입니다. 시퀀스 및 필드 수는 각 serialization에서 다를 수 있으며 문제가 무엇인지 알 수 있습니다. –

+0

버전 관리가 가능한 스키마를 사용할 때 아무런 문제가 없으며 버전 관리가 가능한 스키마가 사용자가 개발 한 문제의 표준 솔루션입니다. 간단한 소개는 [CArchive :: GetObjectSchema] (https://msdn.microsoft.com/en-us/library/wkbc2za4.aspx)와 [TN002 : Persistent Object Data Format] (https : // msdn .microsoft.com/en-us/library/32wxt301.aspx)를 참조하십시오. 어쨌든 질문에 따라 대답 할 수 없습니다. 우리가 공통 기반을 가질 수 있도록 [mcve]를 제공하십시오. – IInspectable

답변

1

strong exepction safety guarantee이없는 경우이 문제를 해결하는 데 잘못된 방법이있는 것처럼 보입니다.

그래서 그들은 그것을 준수하도록 기능을 구현할 수

를 (단지 CArchive 객체의 내부를 좋아하거나 함수 내에서 복사되지 않은 함수의 로컬 오프셋을 사용)하지만 또한 예외가 학대를하는 것 같아 여기 구조를 제어하십시오. 당신은 아마 전용 "뛰어난"상황에 예외를 사용하는 것을 고려하고이 청소기 코드처럼 나에게 보인다 "남용"예외하지 않습니다

if(isFormat1Convertible(ar)) 
{ 
    SerializeEx(ar); 
} 
else if(isFormat2Convertible(ar)) 
{ 
    SpecialSerialize1(ar); 
} 
... 

같은 일부 기능이 있어야합니다.

+0

[Serialization in MFC] (https://msdn.microsoft.com/en-us/library/6bz744w8.aspx)를 이해하지 못하는 사람이 작성한 원유 괴롭힘. 예외는 함수가 약속을 지키지 못할 때 던져 져야한다. 치명적인 (또는 "예외적 인"*) 것은 클라이언트 코드가 결정하는 것입니다. 일반적으로 예외를 throw하는 코드는이 오류가 문맥에서 치명적인 것인지 여부를 거의 알지 못합니다. – IInspectable

+0

예, 이것은 "MFC"방식이 아니지만 "in"언어 대신 "언어"/ 프레임 워크를 프로그래밍하는 것을 선호합니다 (이에 대한 자세한 내용은 "코드 완성"4 장 참조). OP에서이 예외 사용을 "코드 냄새"로 간주하는 인터넷/책에 대한 여러 토론이 있습니다 (OP에는 게시자가 존재하지 않는 다른 문제가 있습니다). 나는 잠시 동안 MFC를 사용하지 않았지만 docu에서 볼 때 "VERSIONABLE_SCHEMA"라는 것이 있습니다. 아마도 이것은 예외 (또는 다른 방법이지만 상황에 따라 다름) 대신 올바른 형식을 선택하는 데 사용될 수 있습니다. – Hayt

+0

프로그램을 작성하든 프로그램을 작성하든간에 교육적 결정을 내릴 수있는 프레임 워크를 알아야합니다. * Code Complete *의 조언에는 이론적 근거가 있습니다. 당신의 통찰력 부족은 그것을 적용하는 것을 박탈합니다. 게다가, 당신이 그것을 변경하고 규칙을 어 기지 않는 한 MFC의 직렬화에 프로그램 할 수 없다. 그리고 여기에 와서 엉망진창에 대한 도움을 청한다. – IInspectable