2016-08-25 7 views
-1

Я пытаюсь составить сериализацию для моего объекта, который может быть из нескольких источников, например Source 1 и Source 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 
      } 
     } 
    } 
} 

EDIT 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; 
     } 
    } 
} 

Это Сериализация код из источника 2

// 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 Последовательность для одного и того же объекта CSerFoo. Мы не можем идти на компромисс по созданию другого класса.

Проблема, с которой я сталкиваюсь, при последующих вызовах сериализации перемещается курсор (CArchive :: m_lpBufCur) и, следовательно, следующая попытка завершения Serialize.

Есть ли способ достичь этого?

Я ничего не пропустил?

Спасибо за кучу заранее!

+1

Не зная, что делают SerializeEx и SpecialSerializeX, сложно сказать об этом. –

+0

Это всего лишь сериализация строк int, float и string в последовательности. Последовательность и количество полей могут различаться в каждой сериализации, вот в чем проблема. –

+0

Нет проблем при использовании версий, доступных для версий, и версий, доступных для версии, являются стандартным решением проблемы, которую вы изобрели. См. [CArchive :: GetObjectSchema] (https://msdn.microsoft.com/en-us/library/wkbc2za4.aspx) для краткого введения, а также [TN002: Формат данных постоянных объектов] (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

Неочищенный клод, написанный кем-то, кто не понимает [Сериализация в MFC] (https://msdn.microsoft.com/en-us/library/6bz744w8.aspx). Что касается исключений, их следует бросить, когда функция не выполнит свое обещание. Независимо от того, является ли это фатальным (или * «исключительным» *), для решения клиентского кода. В общем, код, который генерирует исключение, почти никогда не знает, является ли этот отказ фатальным в контексте. – IInspectable

+0

Да, это не значит, что это «MFC», но я предпочитаю программировать «на» язык/фреймворк вместо «на» языке (см. «Глава 4» для некоторых объяснений). И есть несколько обсуждений в Интернете/книгах, которые рассматривают это использование исключений в OP как «запах кода» (и OP имеет некоторые проблемы с ним, иначе пост не будет существовать). Я не использовал MFC некоторое время, но, как я вижу из документа, есть вещь, называемая «VERSIONABLE_SCHEMA». Возможно, это можно использовать для выбора правильного формата вместо исключений (или других методов, но это зависит от обстоятельств). – Hayt

+0

Вы должны знать рамки, чтобы принять обоснованное решение, хотите ли вы запрограммировать в нем или в нем. Совет от * Code Complete * поставляется с обоснованием. Ваше отсутствие понимания лишает вас возможности применить его. Кроме того, вы не можете запрограммировать сериализацию MFC, если вы не измените ее и не нарушите правила, а затем придите сюда, чтобы обратиться за помощью к беспорядку, с которым вы столкнулись. – IInspectable

 Смежные вопросы

  • Нет связанных вопросов^_^