Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » VC++ / MFC » Serialisierung

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 < [ 2 ]
000
16.08.2005, 18:37 Uhr
~Patrick
Gast


Hallo zusammen!
Ich hab folgendes Problem. Ich möchte Objekte der folgenden selbst erstellten Klasse serialisieren.

C++:
class ClInschrift : public CObject
    {
    DECLARE_SERIAL(ClInschrift)
    
    public:
    ClInschrift()
        {this->text = "";
        this->nummer = "";}
    ClInschrift(string text, string nummer)
        {this->text = text;
        this->nummer = nummer;
        }
    ~ClInschrift() {return;}    //Destruktor
    void Serialize(CArchive & ar);
    
    /*
    ClInschrift & operator = (ClInschrift & zugewiesenesObjekt)    //Copy - Konstruktor
        {
        if (this ==  &zugewiesenesObjekt) return * this;
        this->nummer = zugewiesenesObjekt.nummer;
        this->text = zugewiesenesObjekt.text;
        return * this;
        }
    */


    string displayText() {return text;}
    string displayNummer() {return nummer;}
    
    private:
    string text;
    string nummer;
    };



Die zugehörige Klassenbibliothek sieht wie folgt aus:


C++:
#include "stdafx.h"
#include "ClInschriftHead.h"

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

IMPLEMENT_SERIAL (ClInschrift, CObject, 1)

void ClInschrift::Serialize(CArchive & ar)
    {
    CObject::Serialize(ar);
    if (ar.IsStoring()) ar << nummer << text;
    else ar >> nummer >> text;
    }




Mein Programm liest Daten aus einer Textdatei und speichert diese in Objekten der Klasse ClInschrift. Die Verwaltung dieser Objekte nehme ich mittels des <vector> - Containers der STL vor. Das funktioniert auch alles soweit sehr gut. Möchte ich allerdings diese Anwendung kompilieren, motzt der Compiler:


Zitat:

cProgramme\Microsoft Visual Studio .NET 2003\Vc7\include\vector(810): error C2558: class 'ClInschrift': Kein Kopierkonstruktor verfügbar oder der Kopierkonstruktor is als 'explicit' deklariert



Ich habe eine Testanwendung geschrieben, die die Objekte ohne STL verwaltet, hier tritt der Fehler nicht auf. Ich vermute also, dass die Serialisierung an der STL scheitert.
Darum die Frage:
Wie müsste der Copy - Konstruktor aussehen, um dieses Problem zu vermeiden?
Bzw. wenn jemand einen anderen Grund entdeckt, wäre ich natürlich auch für eine alternative Antwort sehr dankbar!
Herzlichen Dank!
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
17.08.2005, 12:33 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


nimm halt wenn du schon mfc nutzt z.b CArray
--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
17.08.2005, 13:59 Uhr
~Patrick
Gast



Zitat:
nimm halt wenn du schon mfc nutzt z.b CArray

Wär ne Möglichkeit. Dann muss ich aber das gesamte Programm quasi neu schreiben, weil die Grundstrukturen auf die STL - Algorithmen zurückgreifen! Es muss doch auch eine Möglichkeit geben, STL - Strukturen zu serialisieren. Vielleicht auch für den Anfang die gesamte Array - Struktur und nicht einzelne Elemente...
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
17.08.2005, 14:21 Uhr
Tommix



Hallo,
in dem Fall würde ich versuchen, auch zum speichern / laden STL Funtionalität (streams) zu verwenden, aber wie auch immer zum Thema Copykonstruktor siehe hier.

- Tommix
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
17.08.2005, 15:50 Uhr
~Patrick
Gast



Zitat:
aber wie auch immer zum Thema Copykonstruktor siehe hier.

Wie man nen Copy - Konstruktor definiert, ist mir klar. Bei mir haperts am Verständnis, wie ein solcher Konstruktor bei STL - Containern aussieht. In der Praxis weise ich ja keine Objekte der Klasse direkt zu, sondern verwalte die über Iteratoren. Dementsprechend müsste ich ja bei der Überladung von "=" nicht Referenzen auf die eigentlichen Objekte der Klasse übergeben, sondern die Iteratoren. Da hab ich auch schon einiges probiert, die Fehlermeldung bleibt leider trotzdem.

Zitat:
speichern / laden STL Funtionalität (streams)

Hättest du vielleicht ein kurzes Beispiel für die Verwendung eines solchen Streams? Hab damit noch nie gearbeitet!
Patrick
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
17.08.2005, 17:10 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


evtl wärs sinnvoll wenn du uns zeigst wie du den vector von den objekten definierst und wo z.b der fehler von oben "geworfen" wird, also wo diese zuweisung passiert die er nicht durchführen kann.
--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
18.08.2005, 14:38 Uhr
~Patrick
Gast


Also den Aufbau des Vectors nehme ich über die Zeile

C++:
inschriften.push_back(ClInschrift(puffer, nummer));

vor. puffer und nummer sind beides Strings, was ja auch aus der Klassendefinition hervorgeht. Aufgrund bestimmter Textstrukturen der Quelldatei erzeuge ich dann jeweils neue Objekte und schiebe sie in den Vector. Details sind hier wahrscheinlich unnötig.
Die Deklarationen von Vector und Iterator lauten:

C++:
vector <ClInschrift> inschriften;
vector <ClInschrift> ::iterator pos;


Auf die Objekte des Vectors greife ich nur über pos zu. Eine wirkliche Zuweisung nehme ich nicht vor. Der oben genannte Fehler tritt auf, wenn ich die Statements zur Serialisierung
wie bsw. DECLARE_SERIAL usw. (s.o.) in die Klassendeklaration und die Klassenbibliothek aufnehme. Erst zu diesem Zeitpunkt motzt der Compiler, es sei kein passender Copy - Konstruktor verfügbar. Da der Compiler
Zitat:
include\vector(810):...
diese include - Datei als Fehlerquelle angibt, vermute ich, dass die Serialisierungsmethoden auf Assignments zurückgreifen, die in den zu serialisierenden Klassen definiert sein müssen. Allerdings reicht ein "normaler" Copy - Konstruktor, der nur Objekte der Klasse ClInschrift zuweist, aufgrund der STL scheinbar nicht aus, um den Compiler zufriedenzustellen. Ich vermute daher, dass ein angepasster Copy - Konstruktor her muss, der die Verwaltung über Iterator berücksichtigt.
Vielleicht lieg ich da aber auch vollkommen falsch...
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
18.08.2005, 14:59 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


Copy-Konstruktor ist z.b


C++:
CObject(const CObject &Source)



was du da oben auskommentiert hast ist ein zuweisungsoperator. evtl fehlt dir einfach diese variante.
--
class God : public ChuckNorris { };

Dieser Post wurde am 18.08.2005 um 14:59 Uhr von FloSoft editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
19.08.2005, 15:13 Uhr
~Patrick
Gast


Hab auch nen Copy - Konstruktor nach obigem Schema erstellt. Die Problematik bleibt leider die gleiche.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
009
19.08.2005, 15:43 Uhr
mmc20
puss in boots


hi, also am copy-ctor liegts auf keinen fall da für das serialisieren keiner nötig ist.
hier mal ein beispiel einer klasse bei welcher die serialisierung funktioniert (ohne copy-ctor)

C++:
// Data.h : Header-Datei
//

class CData : public CObject
{
    DECLARE_SERIAL (CData)
public:
    CData();
    virtual ~CData();
    void Serialize(CArchive& ar);

// DatenMembers
    int iDiamX, iDiamZ;
    CString sKunde, sName, sControls;
};




C++:
// Data.cpp: Implementierungsdatei
//

#include "stdafx.h"
#include "Data.h"

IMPLEMENT_SERIAL (CData, CObject, 1)

CData::CData()
{
}

CData::~CData()
{
}

void CData::Serialize(CArchive &ar)
{
    CObject::Serialize( ar );

    if ( ar.IsStoring() ) {
        ar << sKunde << sName << sControls;
        ar << iDiamX << iDiamZ;
    } else {
        ar >> sKunde >> sName >> sControls;
        ar >> iDiamX >> iDiamZ;
    }
}


das ganze wird dann in ein "CTypedPtrArray"-member gespeichert:

C++:
    CTypedPtrArray<CObArray, CData*> m_DataArray;

und schon kann man einfach laden/speichern:

C++:
void CDeinDlg::OnLoadDA( CString sFile )
{
    int res = -1;
    CFile file;
    if ( file.Open( sFile, CFile::modeRead ) ) {
        CArchive ar( &file, CArchive::load|CArchive::bNoFlushOnDelete );
        ar >> res;
        m_DataArray.SetSize( res, 10 );
        m_DataArray.Serialize( ar );
    } else
        MessageBox( "Datei nicht vorhanden, oder beschädigt.", " Fatal Error", MB_ICONERROR|MB_OK );
    file.Close();
}

void CDeinDlg::OnSaveDA( CString sFile )
{
    CFile file;
    if ( file.Open( sFile, CFile::modeCreate | CFile::modeWrite ) ) {
        CArchive ar( &file, CArchive::store ); // |CArchive::bNoFlushOnDelete
        ar << m_DataArray.GetSize();
        m_DataArray.Serialize( ar );
    } else
        MessageBox( "Daten konnten nicht gespeichert werden.", " Fatal Error", MB_ICONERROR|MB_OK );
    file.Close();
}


 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 < [ 2 ]     [ 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: