Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » VC++ / MFC » Serialize

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
12.05.2003, 09:55 Uhr
~Michael L.
Gast


Hi,
ich beschäftige mich gerade mit Serialize() und habe ein Problem.
Ich habe ein CObArray und lege da Zeiger auf meine Klasse CTermin ab!

C++:
CTermin::CTermin()
{
    m_time = NULL;
    m_strDescription = new CString("");
}

CTermin::~CTermin()
{
    delete m_strDescription;
    if(m_time!=NULL) delete m_time;
}

void CTermin::Serialize(CArchive &ar)
{
    /// Funktion der Basisklasse aufrufen
    CObject::Serialize(ar);
    /// Wird geschrieben oder gelesen
    if(ar.IsStoring())
    {
        /// Variablen schreiben
        ar << *m_time << *m_strDescription;
    }
    else
    {
        /// Variablen lesen
        ar >> *m_time >> *m_strDescription;
    }
}

void CTermin::SetTime(int sec, int min,int hour,int day,int month, int jear)
{
    m_time = new CTime(jear,month,day,hour,min,sec);
}

void CTermin::SetDescription(CString str)
{
    *m_strDescription = str;
}

CString* CTermin::GetDescription()
{
    return this->m_strDescription;
}


Wenn ich das CObArray Serialisieren möchte geht das auch im mode store soweit. Will ich nun aber die Daten mit mode load wider auslesen, kommt ein
Access Violation.

C++:
CFile* file = new CFile();
if(file->Open(this->m_option->m_strLoad,CFile::modeRead))
{
             try
    {
        CArchive archive(file,CArchive::load);
        this->m_oaTermin.Serialize(archive);
        archive.Close();
    }
    catch(CException* ex)
    {
        TRACE("void CTerminplannerDlg::OnLoad() , cant handle CArchive.\n");
        delete ex;
    }
    file->Close();
}


Mit Debug habe ich herrausgefunden, daß er mit

C++:
void CObArray::Serialize(CArchive& ar)
{
    ASSERT_VALID(this);

    CObject::Serialize(ar);

    if (ar.IsStoring())
    {
        ar.WriteCount(m_nSize);
        for (int i = 0; i < m_nSize; i++)
            ar << m_pData[i];
    }
    else
    {
        DWORD nOldSize = ar.ReadCount();
        SetSize(nOldSize);
        for (int i = 0; i < m_nSize; i++)
            ar >> m_pData[i];
    }
}


eine Operation auf einem NULL-Zeiger machen will. (ar >> m_pData[i]
Is das ein Bug? Muß ich mir anderweitig merken wieviele Objekte ich drin haben und diese erst anlegen bevor ich Serialize(...,mode:store); aufrufe?
Aber das dachte ich macht gerade das Serialize Pattern(Fällt kein besserer Begriff ein) aus?
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
12.05.2003, 17:52 Uhr
mike
Pinguinhüpfer
(Operator)


Hoi!
Von welchem Typ ist m_pData? Was macht die virtuelle Funktion Serialize genau?

mfg mike
--
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
12.05.2003, 18:12 Uhr
~Michael L.
Gast


m_pData sind bei mir Zeiger vom Typ CTermin.
Serialize beschreibt wie du deine Klasse in ein CArchive abspeichern möchtest. Also bei mir: ar << *m_time << *m_strDescription; Ich will mir
den String und das CTime Objekt merken! Diese haben ebenfalls eine Serialie Funktion und so "hangelt" sich das durch.
CObArray.Serialize ruft CTermin.Serialize auf und das dann die Serialize Funktion der Membervariablen! Ok?

Michael L.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
12.05.2003, 19:14 Uhr
mike
Pinguinhüpfer
(Operator)


Ja
Aber warum nutzt du nicht die Funktion CObArray::Add und fügst in CTermin ein Makro ein (DECLARE_SERIAL, IMPLEMENT_SERIAL)?
Scheint mir irgendwie einfacher...
In der MSDN wird das Problem nämlich so gelöst

C++:
CObArray array;
    
array.Add( new CAge( 21 ) ); // Element 0



mfg mike
--
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
12.05.2003, 20:57 Uhr
mike
Pinguinhüpfer
(Operator)


Hi!
So hätte ich das gemacht
http://programmer.cyberhost.tk/mike/test.zip

mfg mike
--
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
13.05.2003, 16:40 Uhr
~Michael L.
Gast


Danke für die Mühe (Das du ein Bsp geschrieben hast.
Das sieht auch besser aus als meine Testumgebung

Zitat:

Aber warum nutzt du nicht die Funktion CObArray::Add und fügst in CTermin ein Makro ein (DECLARE_SERIAL, IMPLEMENT_SERIAL)?


Shit eine Zeile weg gelassen! Ich mache das mit den 2 Makros. Und ich nutze auch die Add Funktion so wie du! Ich sehe eingentlich keinen Unterschied zu deinem Prog. Ausser einen Punkt, den habe ich anders. Kann es sein das er meine Serialize Funktion mit den Pointern so nicht will? (Gebe nochmal die Gesamte Klasse und meine Funktion wo ich einfüge!

C++:
// Termin.h: Schnittstelle für die Klasse CTermin.
//
///////////////////////////////////////////////////
class CTermin : public CObject  
{
    DECLARE_SERIAL(CTermin)
public:
    CString* GetDescription();
    void SetDescription(CString);
    void SetTime(int,int,int,int,int,int);
    CTermin();
    virtual ~CTermin();
    virtual void Serialize (CArchive& ar);
    /// Zugriffsmethoden
private:
    CString* m_strDescription;
    CTime* m_time;

};

// Termin.cpp: Implementierung der Klasse CTermin.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "stdafx.h"
#include "Termin.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

IMPLEMENT_SERIAL (CTermin, CObject, 1)
//////////////////////////////////////////////////////////////////////
// Konstruktion/Destruktion
//////////////////////////////////////////////////////////////////////

CTermin::CTermin()
{
    m_time = NULL;
    m_strDescription = new CString("");
}

CTermin::~CTermin()
{
    delete m_strDescription;
    if(m_time!=NULL) delete m_time;
}

void CTermin::Serialize(CArchive &ar)
{
    /// Funktion der Basisklasse aufrufen
    CObject::Serialize(ar);
    /// Wird geschrieben oder gelesen
    if(ar.IsStoring())
    {
        /// Variablen schreiben
        ar << *m_time << *m_strDescription;
    }
    else
    {
        /// Variablen lesen
        ar >> *m_time >> *m_strDescription;
    }
}

void CTermin::SetTime(int sec, int min,int hour,int day,int month, int jear)
{
    m_time = new CTime(jear,month,day,hour,min,sec);
}

void CTermin::SetDescription(CString str)
{
    *m_strDescription = str;
}

CString* CTermin::GetDescription()
{
    return this->m_strDescription;
}

// Funktion mit der ich einfüge
//////////////////////////////////
/**
* Neuen Termin anlegen und einfügen
*/

bool CTerminplannerDlg::AddNewTermin(CTermin* termin)
{
    try
    {
        this->m_oaTermin.Add(termin);
        this->m_iCurTermin = this->m_oaTermin.GetSize()-1;
    }
    catch(CMemoryException* ex)
    {
        // Benutzer über schlechte Neuigkeiten
        // informieren
        AfxMessageBox("Out of memory", MB_ICONSTOP | MB_OK);
        // Wurde Person-Objekt erzeugt?
        if (termin)
        {
            // Objekt löschen
            delete termin;
            termin = NULL;
        }
        delete ex;
        return false;
    }
    return true;
}


Also nur das ich Zeiger benutze sehe ich keinen Unterschied!

mfg Michael L.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
14.05.2003, 14:16 Uhr
mike
Pinguinhüpfer
(Operator)


Hi!
Die CArchive Operatoren können meines Wissen CString Pointer oder Referenzen nicht so einfach übernehmen. Dü müsstest mit

C++:
CString &operator>>(CString &p_Object);
CString &operator<<(CString &p_Object);


den Operator manipulieren. Dies würde wieder das Erzeugen eines CArchive Pointers zur Folge haben und lohnt sich, meiner Meinung nach, bei 2 Membervariblen nicht.

Aber ich muss noch dazu sagen, dass ich noch nie Pointer in CArchives verwendet habe. Es könnte jetzt natürlich sein, dass der Fehler auch wo anderes ist

mfg mike
--

Dieser Post wurde am 14.05.2003 um 14:25 Uhr von mike editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ VC++ / MFC ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: