Serialize CArray
-
Hi,
ich habe eine Klasse CHistorie, mit einer CArray-MemberVar vom Typ CValue&.
CValue enthält int, CString und bool MemberVar.Wenn ich Serialisiere...
void CHistorie::Serialize(CArchive &ar) { CObject::Serialize(ar); m_Historie.Serialize(ar); // CArray serilisieren if (ar.IsStoring()) ar << m_ID; // integer-Member auch noch serialisieren else ar >> m_ID; }Es werden jetzt alle Member von CValue wieder richtig eingelesen - außer der CString. (bin mir im Debugger nicht sicher, ob er Daten enthält oder auf fremden Speicher zeigt)
Weiß jemand woran das liegen könnte?
-
Du musst diese Funktion
template<class TYPE> void AFXAPI SerializeElements(CArchive& ar, TYPE* pElements, INT_PTR nCount) { ASSERT(nCount == 0 || AfxIsValidAddress(pElements, (size_t)nCount * sizeof(TYPE))); // default is bit-wise read/write if (ar.IsStoring()) { TYPE* pData; UINT_PTR nElementsLeft; nElementsLeft = nCount; pData = pElements; while( nElementsLeft > 0 ) { UINT nElementsToWrite; nElementsToWrite = UINT(min(nElementsLeft, INT_MAX/sizeof(TYPE))); ar.Write(pData, nElementsToWrite*sizeof(TYPE)); nElementsLeft -= nElementsToWrite; pData += nElementsToWrite; } } else { TYPE* pData; UINT_PTR nElementsLeft; nElementsLeft = nCount; pData = pElements; while( nElementsLeft > 0 ) { UINT nElementsToRead; nElementsToRead = UINT(min(nElementsLeft, INT_MAX/sizeof(TYPE))); ar.Read(pData, nElementsToRead*sizeof(TYPE)); nElementsLeft -= nElementsToRead; pData += nElementsToRead; } } }(siehe afxtempl.h)
für deine Klasse CValue überschreiben.
-
Danke erstmal René
Oh je, da seh ich die nächsten Probleme...
Ich habe noch nicht so oft mit Templates gearbeiten - also noch ein paar Fragen:Du hast gesagt ich muss die SerializeElements von CValue überschreiben?
In der Klasse CHistorie habe ich die Membervariable m_Historie:class CHistorie : public CObject { DECLARE_SERIAL(CHistorie) protected: CArray<CValue, CValue&> m_Historie; ...Muss ich jetzt in CValue eine Methode, wie folgt definieren?
void AFXAPI CValue::SerializeElements(CArchive& ar, TYPE* pElements, INT_PTR nCount)Kannst Du mir da mal bitte etwas genauer weiterhelfen? (Oder vielleicht einen Link geben?)
Danke
-
Gibt noch ne simplere Möglichkeit. Und zwar kannst Du Dein CValue von CObject ableiten, dort dann mit DECLARE_SERIAL die Klasse serialisierbar machen, und die Funktion Serialize(...) überschreiben.
Dann fügst Du alle Deine CValue-Elemente nicht in ein CArray<> ein, sondern in ein CObArray. Die Serialize-Funktion von CObArray übernimmt dann das Speichern der einzelnen Elemente, indem sie für jedes Element die Serialize-Funktion aufruft.
-
Serialize hatte ich bei CValue ja schon implementiert, da ich dachte CArray benutzt die Fkt dann auch.
Muss ich bei CObArray irgendwelche Besonderheiten beachten?
Ich habe in der MSDN gelesen,
... dass nur die Zeiger gelöscht werden. Muss ich also beim entfernen das Objekt auch noch selbst löschen?
... Sollte man SetSize vorher aufrufen? Es können bei mir maximal 999 Elemente eingefügt werden. Aber SetSize gleich auf 999 ist doch eftwas heftig oder?
... was hat das mit dem CDumpContext auf sich?
... leite ich meine Array Klasse von CObArray ab oder gibts da auch nen Template?Danke
[ Dieser Beitrag wurde am 02.07.2003 um 09:46 Uhr von MuehBln editiert. ]
-
OK - habs gepackt...
Aber eine Frage noch in dem Zusammenhang.
Beim Löschen von Elementen aus dem CObArray wird ja der Operator delete benutzt. Muss ich den für meine Klasse CValue (Elemente des Arrays) überladen oder lass ich den einfach von CObject?Danke+
-
Löschen aus CObArray:
for( int i=0; i<obArray.GetCount(); i++) delete obArray[i]; // nur delete, falls Du new zum Anlegen benutzt hast!
-
Danke René, klappt jetzt alles.
Habe mal noch eine allg Frage:
Wenn ich eine Klasse von CObject ableite, erbe ich ja den operator new und delete.
Unter welcher Voraussetzung muss man diese in der eigenen Klasse überschreiben?
Oder muss man das nie machen?
-
Muss man nie machen, da diese Operatoren einfach nur auf die globalen new/delete-Operatoren verweisen.