Toon posts:

[C++] Objecten opslaan in een file

Pagina: 1
Acties:

Verwijderd

Topicstarter
Hallo allemaal,

ik heb een volgende vraag: ik ben in Borland Builder 3.0 aan het programmeren en ik wil objecten kunnen opslaan in een file. Ik heb gehoord dat het kan, maar ik kan zelf niets vinden in de help van de builder, dus ik heb jullie hulp nodig. Als iemand iets weet hoor ik het heel erg graag,

alvast bedankt!

  • whoami
  • Registratie: December 2000
  • Laatst online: 07:58
Dat kan inderdaad. Alles kan eigenlijk (koffiekan, kandidaat, kanadees, vork'an de steel)...
Zoek eens in de help op fstream.

https://fgheysels.github.io/


  • PrinsEdje80
  • Registratie: Oktober 2001
  • Laatst online: 01-01 15:26

PrinsEdje80

Holographic, not grated...

Onder linux kun je je eigen library bouwen mbv
code:
1
ar rvs libblaat.a *.o

Waarbij je later objecten uit de library mee compiled mbv
code:
1
g++3 .... -Lblaat -l'locatie'

met 'locatie' de plek waar je dat .a bestand staat.

Used to be Down Under... Foto gallery


  • whoami
  • Registratie: December 2000
  • Laatst online: 07:58
Op vrijdag 15 februari 2002 10:24 schreef PrinsEdje80 het volgende:
Onder linux kun je je eigen library bouwen mbv
code:
1
ar rvs libblaat.a *.o

Waarbij je later objecten uit de library mee compiled mbv
code:
1
g++3 .... -Lblaat -l'locatie'

met 'locatie' de plek waar je dat .a bestand staat.
Ik denk niet dat de topicstarter dit bedoelt. Volgens mij wil hij gewoon objecten van een class (bv. objecten van de classe Persoon ofzo), wegschrijven naar een bestand, om die dan later terug in te kunnen lezen. In dat geval gaat hij best eens de fstream, ifstream, ofstream classes enzo gaan bekijken.

https://fgheysels.github.io/


Verwijderd

Topicstarter
Ja, dat klopt. Ik heb in dit geval een class Component (we maken een simulatie van een netwerk van elektrische componenten) en ik wil die objecten van type component opslaan in een file, maar ik zal fstream e.d. nog wat beter bekijken, maar de help is daar niet echt uitgebreidt in :(.
Dus meer hulp is altijd welkom.

  • whoami
  • Registratie: December 2000
  • Laatst online: 07:58
't is al lang geleden dat ik dat nog gedaan heb, maar je moet dus een object instancieren van de fstream class. Die class heeft nl een aantal member functions zoals open, read, write, eof, close enz. waarmee je file - manipulatie kunt doen.

https://fgheysels.github.io/


  • XTerm
  • Registratie: Juli 2001
  • Laatst online: 10-06-2025
De beste (en meest OO-elegante) manier is de volgende.

Maak een functie

Components::Save(string filename)
{}

Die alle private/public variablen opslaat in een file.
Dan ook nog een Components::Open(string filename), om het terug in te lezen en voila; je bent klaar.

Als het niet lukt; probeer dan met ANSI C te werken voor het save :

FILE *f; // File pointer declareren

f=fopen(char* filename,char* mode); // mode: "r"< read, "w"<read write

fclose(f).

En dan kan je ook met fprintf(..); dingen naar de file saven en met fscanf(..) teruglezen.

Als het je niet lukt post de klasse en ik/andere tweakers schrijft het dan wel voor je.

Verwijderd

Topicstarter
Ok, klinkt goed. Staat deze class ook als *.cpp + *.h file op de schijf? Ik zit nu op school, dus daar kan ik nu niet bij. Of kan ik ergens anders nog vinden welke methoden deze class heeft?

Verwijderd

Op vrijdag 15 februari 2002 10:55 schreef XTerm89D het volgende:
De beste (en meest OO-elegante) manier is de volgende.

Maak een functie

Components::Save(string filename)
{}

Die alle private/public variablen opslaat in een file.
Dan ook nog een Components::Open(string filename), om het terug in te lezen en voila; je bent klaar.
Dit vind ik absoluut niet de meest elegante methode, om de volgende reden:

- de Save methode is niet standaard
- je laat de methode zelf de file openen, daarbij moet je dan append of overwrite enzo ook regelen, fouten afhandelen als het misgaat
- doordat je een filename gebruikt is het niet mogelijk om andere streams te gebruiken dan een file, dus over het hetwerk is het niet mogelijk..

Een betere methode is het overloaden van de operators << en >> voor respectievelijk de istream en de ostream op de volgende manier:

operator<<(ostream& os, const mijnObject& obj);
operator>>(istream& is, mijnObject& obj);

Deze functies handelen dan het naar de stream schrijven en het uit te steam plukken van het object af. Het openen van de stream gebeurt los daarvan, en het maakt ook niet uit watvoor stream het is.

  • XTerm
  • Registratie: Juli 2001
  • Laatst online: 10-06-2025
Oh, jij bedoelde een niet zelf gedefineerde klasse.
Hmmm; dat is moeilijker omdat je niet bij de private members kan komen.

In dat geval, (stoute schoenen aantrekken, to boldly go where no one has gone before), en gewoon dat object dumpen in een file.

Heb ik zelf nooit gedaan, maar misschien lukt het zo :

Maak een char* even groot als sizeof(object);
Dan gebruik je memcpy ed. Om het object in die string te zetten, daarna fprintf("%s",*c); schrijf je het weg in een file.

Lezen is wat ingewikkelder. Dit is waarschijnlijk een groffe (al dan niet werkende) hack, misschien heeft een betere C++'er hier een betere oplossing voor je :)

  • XTerm
  • Registratie: Juli 2001
  • Laatst online: 10-06-2025
Op vrijdag 15 februari 2002 11:02 schreef luite het volgende:

[..]


Een betere methode is het overloaden van de operators << en >> voor respectievelijk de istream en de ostream op de volgende manier:

operator<<(ostream& os, const mijnObject& obj);
operator>>(istream& is, mijnObject& obj);
Bij deze hebt u
(1) Een betere oplossing :)
(2) Een (veel) betere C++ Gotter gevonden :P

  • whoami
  • Registratie: December 2000
  • Laatst online: 07:58
Op vrijdag 15 februari 2002 10:55 schreef XTerm89D het volgende:
De beste (en meest OO-elegante) manier is de volgende.

Maak een functie

Components::Save(string filename)
{}

Die alle private/public variablen opslaat in een file.
Dan ook nog een Components::Open(string filename), om het terug in te lezen en voila; je bent klaar.
Dit is wel de mooiste OO oplossing, maar je zult toch nog moeten gebruik maken van de fstream classes.

In de help is er zeker genoeg info over te vinden, en anders kan je eens op groups.google.com zoeken.

https://fgheysels.github.io/


  • Fvdlaar
  • Registratie: Oktober 2001
  • Laatst online: 06-08 10:57
Op vrijdag 15 februari 2002 10:55 schreef XTerm89D het volgende:
De beste (en meest OO-elegante) manier is de volgende.

Maak een functie

Components::Save(string filename)
{}

Die alle private/public variablen opslaat in een file.
Dan ook nog een Components::Open(string filename), om het terug in te lezen en voila; je bent klaar.
...
Imho is de mooiste OO oplossing om bijv. een klasse Persistent te definieren, met Save en Load methodes, en dan daarvan te inheriten.
Maar het overloaden van de << en >> is veel makkelijker :)

Verwijderd

De >> en << operators implementeren zoals hierboven beschreven is, is slechts een klein onderdeel van het oplossen van het probleem.

Veel belangrijker is om het formaat vast te stellen waarin je de bytestreams op gaat slaan (XML ? ;)), bepalen wie er in jouw systeem verantwoordelijk gaat zijn voor het wegschrijven en laden van objecten, bepalen wanneer er iets moet worden opgeslagen, hoe je relaties en verwijzingen tussen die objecten op gaat slaan, of er slechts één object per keer of hele simulaties moeten worden weggeschreven/opgeslagen, etc.

Met andere woorden: bedenk eerst wat je eigenlijk precies wil, daarna eens hoe je dat wil inbouwen in de rest van het systeem, en daarna met welke objecten/methoden en formaten je dat zou kunnen doen.

Verwijderd

Op vrijdag 15 februari 2002 13:26 schreef Sneech het volgende:
De >> en << operators implementeren zoals hierboven beschreven is, is slechts een klein onderdeel van het oplossen van het probleem.

Veel belangrijker is om het formaat vast te stellen waarin je de bytestreams op gaat slaan (XML ? ;))
Als je de << en >> operators overload om objecten streamable te maken dan staat je formaat vast: je mag volgens de standaard << en >> alleen gebruiken om human readable i/o te doen, dus wordt je formaat in principe een plat tekstbestand.

Verwijderd

Op vrijdag 15 februari 2002 13:37 schreef mietje het volgende:
je mag volgens de standaard << en >> alleen gebruiken om human readable i/o te doen,
Ik geloof er niks van 8-). Kun je misschien vertellen om welke standaard het gaat, en misschien het betreffende stuk citeren ?
dus wordt je formaat in principe een plat tekstbestand.
Het formaat 'plat tekstbestand' is zowieso niet specifiek genoeg om je read/write methoden te implementeren; er zou nog steeds een gedetailleerder formaat verzonnen moeten worden.

Verwijderd

Op vrijdag 15 februari 2002 14:08 schreef Sneech het volgende:
Ik geloof er niks van 8-). Kun je misschien vertellen om welke standaard het gaat, en misschien het betreffende stuk citeren ?
Nou, dan geloof je het toch lekker niet. Je weet best dat ik noch de standaard, noch Stroustrup citeren mag.
Het formaat 'plat tekstbestand' is zowieso niet specifiek genoeg om je read/write methoden te implementeren; er zou nog steeds een gedetailleerder formaat verzonnen moeten worden.
Klopt, maar << en >> impliceert human-readable, de hele iostream lib is hierop gebaseerd. Je gebruikt toch ook << om bv. een double in een voor de mens leesbare vorm te storen, en stream.write() voor een machine-formaat.

  • whoami
  • Registratie: December 2000
  • Laatst online: 07:58
Op vrijdag 15 februari 2002 14:25 schreef mietje het volgende:

[..]

Nou, dan geloof je het toch lekker niet. Je weet best dat ik noch de standaard, noch Stroustrup citeren mag.
Hoezo? waarom niet?
Klopt, maar << en >> impliceert human-readable, de hele iostream lib is hierop gebaseerd. Je gebruikt toch ook << om bv. een double in een voor de mens leesbare vorm te storen, en stream.write() voor een machine-formaat.
Ik wil Arjan_G totaal niet onderschatten, maar ik denk dat het overloaden van de << en >> operator toch een beetje ver gaat voor hetgeen hij gewoon wil.

https://fgheysels.github.io/


Verwijderd

Op vrijdag 15 februari 2002 14:25 schreef mietje het volgende:

[..]

Nou, dan geloof je het toch lekker niet. Je weet best dat ik noch de standaard, noch Stroustrup citeren mag.
Ach man, je begrijpt toch wel dat je stelling zo niet geloofwaardiger wordt :? |:( Stroustrop citeren is trouwens zowieso overbodig in dit geval, omdat het gaat om de standaard zoals die door het C++ commitee is opgesteld.
[..]

Klopt, maar << en >> impliceert human-readable, de hele iostream lib is hierop gebaseerd. Je gebruikt toch ook << om bv. een double in een voor de mens leesbare vorm te storen, en stream.write() voor een machine-formaat.
Het gaat hier weer om conventie vs. standaard. Conventies zijn leuk, maar er is een reden dat ze niet in de standaard zijn opgenomen.

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 20:44

Creepy

Tactical Espionage Splatterer

Aangezien ie met C++ Builder bezig is... hiero een VCL oplossing

Maak gebruik van de TFileStream;
code:
1
2
3
4
5
6
var strm: TFileStream;
begin
  strm := TFileStream.Create('MyList.DAT', fmCreate);
  strm.WriteComponent(MijnComponenthiero);
  strm.Free;
end;

Dit is de Delphi code.. maar omzetten naar C++ Builder code is een eitje.

Het object dat je wil schrijven moet dan wel een afgeleide zijn van TComponent (dus niet je eigen klasse TComponent, maar de VCL klasse TComponent)

En uiteraard bestaat de method readcomponent ook :)

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 23:11
Op vrijdag 15 februari 2002 10:55 schreef XTerm89D het volgende:
De beste (en meest OO-elegante) manier is de volgende.

Maak een functie

Components::Save(string filename)
{}

Die alle private/public variablen opslaat in een file.
Dan ook nog een Components::Open(string filename), om het terug in te lezen en voila; je bent klaar.
Save is simpel: dan weet je al wat voor object je hebt. Maar heb je nagedacht over het feit dat je nog niet weet of je een Component hebt, of een Widget, als je iets will Openen ?
Als het niet lukt; probeer dan met ANSI C te werken voor het save :

FILE *f; // File pointer declareren

f=fopen(char* filename,char* mode); // mode: "r"< read, "w"<read write

fclose(f).

En dan kan je ook met fprintf(..); dingen naar de file saven en met fscanf(..) teruglezen.
Dat wordt lachen als je een std::string hebt.

De standaard method is inderdaad via #include <fstream>
en operator<<. De built-in types hebben nl. geen int::Save methoden en zo, maar wel operator<<(ostream&,int)

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 23:11
Op vrijdag 15 februari 2002 10:57 schreef Arjan_G het volgende:
Ok, klinkt goed. Staat deze class ook als *.cpp + *.h file op de schijf? Ik zit nu op school, dus daar kan ik nu niet bij. Of kan ik ergens anders nog vinden welke methoden deze class heeft?
<fstream> staat typisch wel bij de compiler, maar is zo goed als onleesbaar. Dat maakt ook niet uit; elk goed C++ boek legt uit hoe <fstream> werkt. Zelfs oudere boeken die uitleggen hoe <fstream.h> werkte leggen het soms nog redelijk uit.

De methods die je nodig hebt zijn de ctor: fstream::fstream(filename), fstream::close() en operator<<(ostream&, T) om een type T te schrijven. Als je zelf een type definieert, moet je dus zelf operator<<(ostream&, Type) schrijven. Meestal hoef je alleen alle members van Type te schijven.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • SG
  • Registratie: Januari 2001
  • Laatst online: 13-09 07:59

SG

SG surft naar info hardewaren

code:
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
class screenmode
// Gamevars.h

{
protected:
    int  x_screen;
    int  y_screen;
    int  buffers;
    int  bitdept;
public:
    screenmode():x_screen(800),y_screen(600),buffers(2),bitdept(16),modefromdisk(FALSE)
        {}
    bool modefromdisk;
    void SetDefault()
    {     
        int x_screen=800;   int y_screen=600;   int buffers=2;  int bitdept=16;
    
    } 

    int GetXres(){ return x_screen;}
    int GetYres(){ return y_screen;}
    int GetBufs(){ return buffers;}
    int GetBits(){ return bitdept;}

    void diskin();
    void diskout();
    void dispmode();
};
//screenmode modecfg;

//
//klas voor veld te save lade en initen onk onk onk
//

Zoiets misschien

X399 Taichi; ThreadRipper 1950X; 32GB; VEGA 56; BenQ 32" 1440P | Gigbyte; Phenom X4 965; 8GB; Samsung 120hz 3D 27" | W2012SER2; i5 quadcore | Mac mini 2014 | ATV 4g | ATV 4K


  • SG
  • Registratie: Januari 2001
  • Laatst online: 13-09 07:59

SG

SG surft naar info hardewaren

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// Gamevars.cpp
#include "gamevars.h"
extern SetupInits ScreenVars ={800,600,16,2};
extern screenmode modecfg;

void screenmode::diskin()
{
ifstream infile;
infile.open("mode.cfg",ios::binary);
infile.read( (char*)this, sizeof(*this));
}
void screenmode::diskout()
{
ofstream outfile;
outfile.open("mode.cfg",ios::binary);
outfile.write( (char*)this, sizeof(*this));
}

void screenmode::dispmode()
{

}

'n Object die zich kan wegschrijven maar ook kan laden ofzoiets.

Stond in 'n OOP boek en dit 's mijn toepassing ervan.

X399 Taichi; ThreadRipper 1950X; 32GB; VEGA 56; BenQ 32" 1440P | Gigbyte; Phenom X4 965; 8GB; Samsung 120hz 3D 27" | W2012SER2; i5 quadcore | Mac mini 2014 | ATV 4g | ATV 4K


  • whoami
  • Registratie: December 2000
  • Laatst online: 07:58
Op vrijdag 15 februari 2002 19:13 schreef SuperG het volgende:
code:
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
class screenmode
// Gamevars.h

{
protected:
    int  x_screen;
    int  y_screen;
    int  buffers;
    int  bitdept;
public:
    screenmode():x_screen(800),y_screen(600),buffers(2),bitdept(16),modefromdisk(FALSE)
        {}
    bool modefromdisk;
    void SetDefault()
    {     
        int x_screen=800;   int y_screen=600;   int buffers=2;  int bitdept=16;
    
    } 

    int GetXres(){ return x_screen;}
    int GetYres(){ return y_screen;}
    int GetBufs(){ return buffers;}
    int GetBits(){ return bitdept;}

    void diskin();
    void diskout();
    void dispmode();
};
//screenmode modecfg;

//
//klas voor veld te save lade en initen onk onk onk
//

Zoiets misschien
Wat is het nut hiervan?? Heeft toch niets met file-operaties te maken?

https://fgheysels.github.io/


  • SG
  • Registratie: Januari 2001
  • Laatst online: 13-09 07:59

SG

SG surft naar info hardewaren

Op vrijdag 15 februari 2002 19:21 schreef whoami het volgende:

[..]

Wat is het nut hiervan?? Heeft toch niets met file-operaties te maken?
Dit is 'n voorbeeldje voor 'n object naar disk te saven.

als je deze code wat verder uitbreid kan je meerdere objecten naar 'n file schrijven het is dus

Ontopic Objecten opslaan in file
ik geef hier 'n voorbeeld van een enkele object. dat lijkt mij erg ontopic of ie dat bedoeld is 'n tweede.

Alleen is dit MS VC++ das weer offtopic.

X399 Taichi; ThreadRipper 1950X; 32GB; VEGA 56; BenQ 32" 1440P | Gigbyte; Phenom X4 965; 8GB; Samsung 120hz 3D 27" | W2012SER2; i5 quadcore | Mac mini 2014 | ATV 4g | ATV 4K


  • whoami
  • Registratie: December 2000
  • Laatst online: 07:58
Op vrijdag 15 februari 2002 19:27 schreef SuperG het volgende:

Dit is 'n voorbeeldje voor 'n object naar disk te saven.

als je deze code wat verder uitbreid kan je meerdere objecten naar 'n file schrijven het is dus

Ontopic Objecten opslaan in file
ik geef hier 'n voorbeeld van een enkele object. dat lijkt mij erg ontopic of ie dat bedoeld is 'n tweede.

Alleen is dit MS VC++ das weer offtopic.
Daarvoor was die 2de lap code van u wel voldoende. Die class definitie doet eigenlijk niet zoveel terzake.

https://fgheysels.github.io/


  • Orphix
  • Registratie: Februari 2000
  • Niet online
Op vrijdag 15 februari 2002 19:18 schreef SuperG het volgende:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// Gamevars.cpp
#include "gamevars.h"
extern SetupInits ScreenVars ={800,600,16,2};
extern screenmode modecfg;

void screenmode::diskin()
{
ifstream infile;
infile.open("mode.cfg",ios::binary);
infile.read( (char*)this, sizeof(*this));
}
void screenmode::diskout()
{
ofstream outfile;
outfile.open("mode.cfg",ios::binary);
outfile.write( (char*)this, sizeof(*this));
}

void screenmode::dispmode()
{

}

'n Object die zich kan wegschrijven maar ook kan laden ofzoiets.

Stond in 'n OOP boek en dit 's mijn toepassing ervan.
Mjoah kan wel, maar is erg gevaarlijk. Hier ga je er vanuit dat een object in het geheugen _precies_ hetzelfde eruit ziet als het 'object' in het bestand. Er zijn zoveel randvoorwaarden dat je er niet vanuit mag gaan dat het zo is. Stel je eens voor dat later de klasse structuur wordt aangepast, kan je dan nog oude bestanden openen?
Of dat je het programma met een andere compiler compileert, doet die het dan nog? Of ander OS?

De beste oplossing is een formaat te bepalen en stuk voor stuk de waarden uit te schrijven (binary of ascii). Of je kan, tegenwoordig ook wel populair, via XML de waarden opslaan.

  • SG
  • Registratie: Januari 2001
  • Laatst online: 13-09 07:59

SG

SG surft naar info hardewaren

Dat OOP boek gaat er wel wat dieper op in dan ik hier effe laat zien en de schrijver houd er natuurlijk rekening mee.

Maar dan moet je effe de betreffende boek lezen.
Object-Oriented Programming in C++
3ed Robert Lafore

ANSI/ISO C++

X399 Taichi; ThreadRipper 1950X; 32GB; VEGA 56; BenQ 32" 1440P | Gigbyte; Phenom X4 965; 8GB; Samsung 120hz 3D 27" | W2012SER2; i5 quadcore | Mac mini 2014 | ATV 4g | ATV 4K


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 23:11
Op vrijdag 15 februari 2002 14:28 schreef whoami het volgende:

Ik wil Arjan_G totaal niet onderschatten, maar ik denk dat het overloaden van de << en >> operator toch een beetje ver gaat voor hetgeen hij gewoon wil.
Nee hoor, overloaden van operator<< voor output is iets voor een beginners cursus. Het is een stuk makkelijker dan pointers, bijvoorbeeld.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 23:11
Op vrijdag 15 februari 2002 19:39 schreef Orphix het volgende:

[..]

Mjoah kan wel, maar is erg gevaarlijk. Hier ga je er vanuit dat een object in het geheugen _precies_ hetzelfde eruit ziet als het 'object' in het bestand. Er zijn zoveel randvoorwaarden dat je er niet vanuit mag gaan dat het zo is.
Erger nog - je schrijft alle pointers weg, niet waar die pointers naar toe wijzen. Leuk dat je bij het laden weet dat er de vorige keer iets op adres 0x07328A8C stond :)

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Niet met geheugen dumpen gaan werken omdat je je objecten niet goed terug kan krijgen als je structuur erg verandert. XML is voor dit soort dingen ideaal. Ik gebruik zelf alleen nog maar XML voor dit soort dingen.

ps. ik ben java progger maar voor c en c++ zijn er ook wel libs.

  • Gerco
  • Registratie: Mei 2000
  • Laatst online: 04:29

Gerco

Professional Newbie

Het wegschrijven van objecten in een bepaald formaat daargelaten. Hoe ga je referentief TUSSEN objecten weer restoren?

Stel ik heb een object Object met de volgende members:
code:
1
2
3
4
5
class Object {
  public:
  Object* nogeenobject;
  Object* tweedeobject;
}

Ik maak hiervan 3 instanties A, B en C en link ze zo aan elkaar:
code:
1
2
3
  A
 / \
B - C

Kan iemand hier dan een oplossing bedenken voor het opslaan en restoren van de onderlinge referenties?

- "Als ik zou willen dat je het begreep, legde ik het wel beter uit!" | All number systems are base 10!


Verwijderd

Op zondag 17 februari 2002 16:00 schreef Gerco het volgende:
Het wegschrijven van objecten in een bepaald formaat daargelaten. Hoe ga je referentief TUSSEN objecten weer restoren?
Lijkt me vrij eenvoudig. Tijdens runtime gebruiken (zijn) pointers geheugenadressen om naar objecten te verwijzen. Aangezien je deze geheugenadressen niet hebt als je de objecten opslaat naar een file, moet je dus een andere identificatie-methode verzinnen, zoals bijvoorbeeld een
code:
1
int id;

:)

  • Gerco
  • Registratie: Mei 2000
  • Laatst online: 04:29

Gerco

Professional Newbie

een int id is inderdaad vaak een oplossing, maar hoe ga je die genereren? Als je namelijk gewoon voor iedere referentie een id maakt, loop je met deze situatie tegen de lamp denk ik zo:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Voor:
    A
     / \
    B   C
     \ /
    D
    |
    E
Na:
    A
     / \
    B   C
   /     \
  D  D
 /     \
E        E

Of heb ik het nou mis?

- "Als ik zou willen dat je het begreep, legde ik het wel beter uit!" | All number systems are base 10!


Verwijderd

Op zondag 17 februari 2002 16:17 schreef Gerco het volgende:
een int id is inderdaad vaak een oplossing, maar hoe ga je die genereren? Als je namelijk gewoon voor iedere referentie een id maakt, loop je met deze situatie tegen de lamp denk ik zo:
code:
1
schema'tje..

Of heb ik het nou mis?
Ik zie het probleem niet helemaal. Als je de objecten bij het instantiëren meteen unieke id's geeft, en bij het wegschrijven naar een file de referenties als id-nummers opslaat, moet alles toch goed gaan :?

  • SG
  • Registratie: Januari 2001
  • Laatst online: 13-09 07:59

SG

SG surft naar info hardewaren

TypeID() function heeft wel RTTI nodig.

X399 Taichi; ThreadRipper 1950X; 32GB; VEGA 56; BenQ 32" 1440P | Gigbyte; Phenom X4 965; 8GB; Samsung 120hz 3D 27" | W2012SER2; i5 quadcore | Mac mini 2014 | ATV 4g | ATV 4K


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 23:11
Op zondag 17 februari 2002 16:00 schreef Gerco het volgende:
Het wegschrijven van objecten in een bepaald formaat daargelaten. Hoe ga je referentief TUSSEN objecten weer restoren?

Stel ik heb een object Object met de volgende members:
code:
1
2
3
4
5
class Object {
  public:
  Object* nogeenobject;
  Object* tweedeobject;
}

Ik maak hiervan 3 instanties A, B en C en link ze zo aan elkaar:
code:
1
2
3
  A
 / \
B - C

Kan iemand hier dan een oplossing bedenken voor het opslaan en restoren van de onderlinge referenties?
Ja.

Tijdens de schrijfactie creeer je een std::map<object*, int>. Voor elk object dat je schrijft, check je of het al in de map staat. Zoniet, dan zet je de ptr en z'n nieuwe nieuwe id (=map.size()) in de map , plus je roept (recursief) de functie aan om de twee andere objecten te nummeren. Zodra alle object pointers in da map staan kun
je dan alle objecten saven. Je geeft elk object z'n eigen Id mee ( zoek "this" in de map ), en de twee pointers vervang je ook door hun Id's. Save wel aan het begin het aantal objecten !

Laden gaat nu simpel : allocate ruimte voor alle objecten,
laad object N op base+N, en de twee Id's X en Y worden nu pointers naar base+X en base+Y.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


Verwijderd

Topicstarter
Nou iedereen, het is wel gelukt nu. Ik zal even laten zien wat het geworden is , misschien dat andere mensen er nog wat aan hebben.

Dit is de methode voor het uitlezen van het bestand:

bestandsWijzer = FileOpen(DlbBestandOpenen->FileName, fmOpenRead);
bestandsLengte = FileSeek(bestandsWijzer,0,2);
FileSeek(bestandsWijzer,0,0);

FileRead(bestandsWijzer, tekenComponenten[0], sizeof(TekenComponent));
FileRead(bestandsWijzer, tekenComponenten[1], sizeof(TekenComponent));
FileRead(bestandsWijzer, tekenComponenten[2], sizeof(TekenComponent));
FileRead(bestandsWijzer, tekenComponenten[3], sizeof(TekenComponent));
FileRead(bestandsWijzer, tekenComponenten[4], sizeof(TekenComponent));

FileClose(bestandsWijzer);

Dit is de methode voor het opslaan van de objecten in een bestand.

DlbBestandOpslaan->Filter = "Simulatie bestanden|*.SIM";
DlbBestandOpslaan->FileName = "Simulatie.sim";
DlbBestandOpslaan->Title = "Simulatiebestand opslaan";
DlbBestandOpslaan->Execute();

int bestandsWijzer;

bestandsWijzer = FileCreate(DlbBestandOpslaan->FileName);

while (huidigeTekenComponent < maxAantalComponenten) {
tempTekenComponent = tekenComponenten[huidigeTekenComponent];
FileWrite(bestandsWijzer, tempTekenComponent , sizeof(*tempTekenComponent));
huidigeTekenComponent++;
}

  • whoami
  • Registratie: December 2000
  • Laatst online: 07:58
Op zaterdag 23 februari 2002 18:11 schreef Arjan_G het volgende:

Dit is de methode voor het uitlezen van het bestand:

lap code geknipped
Kun je er even code-tags omheen zetten, dan leest het wat makkelijker.

https://fgheysels.github.io/


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 23:11
Op zaterdag 23 februari 2002 18:11 schreef Arjan_G het volgende:
Nou iedereen, het is wel gelukt nu. Ik zal even laten zien wat het geworden is , misschien dat andere mensen er nog wat aan hebben.
Om heel eerlijk te zijn : Nee.
code:
1
2
3
4
5
6
7
8
9
Dit is de methode voor het uitlezen van het bestand:

         bestandsWijzer = FileOpen(DlbBestandOpenen->FileName, fmOpenRead);
        bestandsLengte = FileSeek(bestandsWijzer,0,2);
        FileSeek(bestandsWijzer,0,0);

        FileRead(bestandsWijzer, tekenComponenten[0], sizeof(TekenComponent));...
        FileRead(bestandsWijzer, tekenComponenten[4], sizeof(TekenComponent));
        FileClose(bestandsWijzer);
Leuk voor een microscopisch projectje, maar wie heeft er nu altijd precies 5 tekenobjecten die allemaal precies even groot zijn ? Bv een rechthoek heeft 4 ints nodig; een vierkant 3, dus hoe weet je nou hoeveel bytes je moet lezen?

Afgezien daarvan is FileRead/FileOpen/FileClose geen C++.
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Dit is de methode voor het opslaan van de objecten in een bestand.

   DlbBestandOpslaan->Filter    = "Simulatie bestanden|*.SIM";
    DlbBestandOpslaan->FileName  = "Simulatie.sim";
    DlbBestandOpslaan->Title     = "Simulatiebestand opslaan";
    DlbBestandOpslaan->Execute();

    int bestandsWijzer;

    bestandsWijzer = FileCreate(DlbBestandOpslaan->FileName);

    while (huidigeTekenComponent < maxAantalComponenten) {
      tempTekenComponent = tekenComponenten[huidigeTekenComponent];
      FileWrite(bestandsWijzer, tempTekenComponent , sizeof(*tempTekenComponent));
      huidigeTekenComponent++;
    }
Als je een for-lus bedoelt schrijf die dan ook. Hier ontbreekt bv. iets essentieels als huidigeTekenComponent=0. Ook FileWrite is geen C++.

Al met al niet iets wat je aan anderen als voorbeeld wil geven.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein

Pagina: 1