Toon posts:

[MFC/C++] Serialiseren eigen objecten

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik zal eerst proberen uit te leggen wat ik heb en wil:

Ik heb:

- een MFC MDI applicatie
- 3 klasses: CVoorraad, CPartij en CItem

Ik wil in een tekstfile de 3 klasses wegschrijven, dmv. de 3 klasses te serialiseren.

Ik zal nu proberen uit te leggen hoe de samenhang van de 3 klasses in mijn applicatie is:
- CVoorraad bevat een vector met alle Partijen die in de voorraad aanwezig zijn.
- CPartij bevat een attribuut dat van het type CItem is
- CItem is niks meer van een omschrijving van de items waaruit EEN partije bestaat
- CVoorraad bevat een vector met alle Items

De header files van de 3 klasses zien er als volgt uit:

CVoorraad:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include "Partij.h"
#include <vector>
using namespace std;

class CVoorraad  
{

private:
    int m_Jaargang;
    CString m_Titel;
    CString m_VoorraadOmschrijving;
    vector<CPartij*> m_Partijen;
    vector<CItem*> m_Items;
    
public:
    CVoorraad(CString jaar, CString titel, CString omschrijving, 
                            vector<CPartij*> *pVecPartijen, vector<CItem*> *pVecItems);
    virtual ~CVoorraad();

    BOOL addPartij(CPartij *);
    BOOL delPartij(int partijID);
    CPartij* getPartij(int partijID);
    CString getJaargang();
    int getAantalPartijen();
    CString getTitel();

    BOOL addItem(CItem *itemID);
    BOOL delItem(int itemID);
    CItem* getItem(int itemID);

    float berekenTotaalWaarde();
    float berekenTotaalGewicht();

    void Serialize(CArchive & ar);

};


CPartij
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include "Item.h"

class CPartij
{

private:
    int m_PartijID;
    CItem m_PartijOmschrijving;
    int m_VoorraadAantal;
    float m_PartijWaarde;
    float m_PartijGewicht;

public:
    CPartij();
    CPartij(int ID, CItem omschrijving, int aantal);
    virtual ~CPartij();

    int getPartijID();
    float getPartijWaarde();
    float getPartijGewicht();
    int getVoorraadAantal();

    void setVoorraadAantal(int aantal);

    BOOL stopItemInVoorraad();
    BOOL neemItemUitVoorraad();

    void Serialize(CArchive & ar);

};


CItem
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <iostream>
using namespace std;

class CItem  
{
private:
    int m_ItemID;
    CString m_ItemNaam;
    CString m_ItemOmschrijving;
    float m_ItemPrijs;
    float m_ItemGewicht;
    
public:
    CItem();
    CItem(int ID, CString naam, CString omschrijving, float prijs, float gewicht);
    virtual ~CItem();

    void setItemNaam(CString naam);
    void setItemOmschrijving(CString omschrijving);
    void setItemPrijs(float prijs);
    void setItemGewicht(float gewicht);

    int getItemID();
    CString getItemNaam();
    CString getItemOmschrijving();
    float getItemPrijs();
    float getItemGewicht();

    void Serialize(CArchive & ar);
    
};


Ik weet hoe men doet serialiseren in MFC, maar ik weet niet hoe ik moet serialiseren als bijvoorbeeld de klasse CPartij een attribuut bevat van het type CItem.
Hier ligt dus ook mijn probleem, want in mijn applicate is dat dus het geval.

Zoals men kan zien in de header file van CPartij, bevat die een attribuut van het type CItem, namelijk m_PartijOmschrijving. Deze moet ook geserialiseerd worden, maar volgens mij gaat dat niet op de volgende manier:

C++:
1
2
3
4
5
6
7
8
    if (ar.IsStoring())
    {
        ar << m_PartijID << m_PartijOmschrijving << m_VoorraadAantal << m_PartijGewicht << m_PartijWaarde;
    }
    else
    {
        ar >> m_PartijID >> m_PartijOmschrijving >> m_VoorraadAantal >> m_PartijGewicht >> m_PartijWaarde;
    }   


Hoe zou dit wel moeten/kunnen?

Dan heb ik nog een vraag, namelijk:

Ik heb 2 vectoren, EEN voor de Partijen en EEN voor de Items, beide vectoren moeten in EEN tekstbestand komen. Het wegschrijven is niet zo moeilijk, maar het trug halen (deserialiseren) is wat lastiger. Want hoe weet ik nu of ik een Item aan het deserialiseren ben of een Partij!?

Ik hoop dat mijn probleem een beetje helder is zo, en dat men mij op weg kan helpen?

Verwijderd

Schrijf er een string bij die aangeeft welke klasse het is... Die serialize je mee, en naderhand kan je aan de hand daarvan bepalen welke klasse je inleest...

of zeg ik iets stoms :? (ben een beetje een C++ n00b, want we hebben pas 3 blokken c++ op school gehad)

Verwijderd

Topicstarter
OK, daar was ik zojuist ook achter gekomen dat dat een optie zou zijn om onderscheid te maken tussen de verschillende klasses!

Maar nu nog mijn andere probleem !? Alle suggesties zijn welkom!

Verwijderd

Verwijderd schreef op 26 mei 2004 @ 15:42:
OK, daar was ik zojuist ook achter gekomen dat dat een optie zou zijn om onderscheid te maken tussen de verschillende klasses!

Maar nu nog mijn andere probleem !? Alle suggesties zijn welkom!
Om de links te leggen kan je het volgende doen:

geef alle dingen een ID. Dus bij het scrhijven geef je allen partijen en items de zelfde ID mee (dus alle items van partij 1 krijgen id 1 mee).

Bij het inlezen koppel je aan de hand hiervan de items weer aan partijen

Verwijderd

Topicstarter
Verwijderd schreef op 26 mei 2004 @ 15:44:
[...]


Om de links te leggen kan je het volgende doen:

geef alle dingen een ID. Dus bij het scrhijven geef je allen partijen en items de zelfde ID mee (dus alle items van partij 1 krijgen id 1 mee).

Bij het inlezen koppel je aan de hand hiervan de items weer aan partijen
Ja dat is een mogelijkheid waar ik nog niet aan gedacht had, maar ik denk dat er wel een mooiere oplossing moet zijn!

Dat je gewoon kan zeggen in je code van:

C++:
1
ar << m_OMschrijving;


Waar m_Omschrijving van het type CItem is (zie openings post)!

  • whoami
  • Registratie: December 2000
  • Laatst online: 11:33
Heb je het eigenlijk al eens zo geprobeerd?

code:
1
ar << m_Omschrijving;


En wat gebeurd er dan ? Wat lukt er dan niet, etc...

https://fgheysels.github.io/


  • koli-man
  • Registratie: Januari 2003
  • Laatst online: 13-05 14:28

koli-man

Bartender!!!!

Volgens mij maak je het jezelf trouwens erg lastig om in de class CVoorraad pointers in je vector op te nemen en niet gewoon het object.
Want je zal ook nog zoiets als een copy constructor moeten maken in je classes.

Hey Isaac...let's go shuffleboard on the Lido - deck...my site koli-man => MOEHA on X-Box laaaiiiff


Verwijderd

Topicstarter
koli-man schreef op 26 mei 2004 @ 16:33:
Volgens mij maak je het jezelf trouwens erg lastig om in de class CVoorraad pointers in je vector op te nemen en niet gewoon het object.
Want je zal ook nog zoiets als een copy constructor moeten maken in je classes.
Waarom zou ik copy constructors moeten maken ?

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22-05 23:07

.oisyn

Moderator Devschuur®

Demotivational Speaker

Dat hoeft ook niet, aan je code te zien is een CVoorraad niet de eigenaar van zo'n CParty of een CItem. Degene die die add* functies aanroept op CVoorraad is zelf verantwoordelijk voor constructie en destructie, en dus hoeven er in de copyconstructor ook geen kopieën gemaakt te worden

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • koli-man
  • Registratie: Januari 2003
  • Laatst online: 13-05 14:28

koli-man

Bartender!!!!

Verwijderd schreef op 26 mei 2004 @ 18:24:
[...]


Waarom zou ik copy constructors moeten maken ?
Nee, ok inderdaad niet moeten, maar ik vind het een goede gewoonte. (canonical)

Hey Isaac...let's go shuffleboard on the Lido - deck...my site koli-man => MOEHA on X-Box laaaiiiff


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 04:19
De standaard stream operators zijn niet echt geschikt voor serialization. Je kunt waarschijnlijk wel een heel eind komen nadat je de C++ FAQ lite over Serialization and Unserialization doorgenomen hebt. Daar worden de verschillende mogelijk redelijk compleet opgesomd, al zul je daar nog geen kant-en-klare oplossing vinden (alleen de benodigde kennis om die zelf te schrijven ;)).

edit:
Zoals .oysin al had gemerkt had ik inderdaad niet goed opgelet; het ging dus over serialization met behulp van MFC.

[ Voor 13% gewijzigd door Soultaker op 26-05-2004 20:40 ]


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22-05 23:07

.oisyn

Moderator Devschuur®

Demotivational Speaker

Soultaker: even goed opletten, de operatoren werken op een CArchive, die is ervoor bedoelt om objecten te (un)serializen ;)

[ Voor 12% gewijzigd door .oisyn op 26-05-2004 20:14 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Verwijderd

Topicstarter
OK, ik heb nog eens nagedacht over mijn probleem en ben er nu achter gekomen dat men ook complete CMap's (=HashTable) kan serialiseren!

Alleen waarom krijg ik dit dan niet werkende?

C++:
1
2
3
4
5
6
7
8
9
10
11
12
void CVoorraad::Serialize(CArchive & ar)
{
    if (ar.IsStoring()) 
    {
        ar << m_PartijMap << m_ItemMap;
    }
    else
    {
                                // hier zit de fout
        ar >> m_PartijMap >> m_ItemMap;
    }
}

m_PartijMap en m_ItemMap, zijn beide een CMapStringToPtr!

De fout zit 'm in in de else, hij komt met de volgende melding:

code:
1
2
error C2679: binary '>>' : no operator defined which takes a right-hand operand 
of type 'class CMapStringToPtr *' (or there is no acceptable conversion)


Wat ik opmaak uit deze foutmelding is dat er GEEN >>-operator is gedefineerd voor "CMapStringToPtr *", maar WEL een <<-operator!

Kortom ik zou ze dus wel kunnen wegschrijven, maar niet meer kunnen inlezen? Ik doe vast iets verkeerd, of ik begrijp het niet goed, maar ik zou op dit moment wel enige hulp kunnen gebruiken! :D

Hoe zorg ik er voor dat ik ook >>-operator kan gebruiken?
Pagina: 1