AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Eine Liste von Objekten speichern

Ein Thema von Luckie · begonnen am 14. Nov 2006 · letzter Beitrag vom 14. Nov 2006
Antwort Antwort
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#1

Eine Liste von Objekten speichern

  Alt 14. Nov 2006, 17:35
Ich versuche gerade verzweifelt eine Liste von Objekten zu speichern:
Delphi-Quellcode:
type
  TForm1 = class(TForm)
    ListBox1: TListBox;
    btnKundeNeu: TButton;
    procedure btnKundeNeuClick(Sender: TObject);
  private
    { Private declarations }
    FKundenListe: array of TBankKunde;
    procedure UpdateListbox;
  public
    { Public declarations }
  end;

var
  Form1 : TForm1;

const
  FRMCAPTION = 'Meine kleine Bank - %s';

implementation

{$R *.dfm}

procedure TForm1.UpdateListbox;
var
  i : Integer;
  KundenName : string;
  BankKunde : TBankKunde;
begin
  Listbox1.Clear;
  for i := 0 to length(FKundenListe) - 1 do
  begin
    BankKunde := TBankKunde.Create;
    try
      BankKunde := FKundenListe[i];
      KundenName := BankKunde.Name;
    finally
      BankKunde.Free;
    end;
    ListBox1.Items.Add(KundenName);
  end;
end;

procedure TForm1.btnKundeNeuClick(Sender: TObject);
var
  BankKunde : TBankKunde;
  KundenName : string;
  len: Integer;
begin
  KundenName := InputBox('Neuer Kunden', 'Name des Kunden:', '');
  BankKunde := TBankKunde.Create;
  try
    try
      BankKunde.Name := KundenName;

      len := length(FKundenListe);
      SetLength(FKundenListe, len + 1);
      FKundenListe[len] := BankKunde;
    except
      on E: Exception do
        MessageBox(Handle, PChar(E.Message), PChar('Neuen Kunde anlegen'), MB_ICONSTOP);
    end;
  finally
    BankKunde.Free;
  end;
  UpdateListbox;
end;
Aber die Listbox bleibt leer. Nehme ich das BankKunde.Free in Zeile 64 weg, geht es genau einmal. Will ich ein zweites Objekt hinzufügen bekomme ich eine AccessViolation.

Ich habe auch schon versucht mit einer TList zu arbeiten, aber das hat auch nicht geklappt. Es muss doch eine Möglichkeit geben ein Objekt zu speichern und nicht nur einen Zeiger auf das Objekt, der wieder ungültig wird, wenn das Objekt freigegeben wird. Oder muss ich mir extra eine Klasse TKundenListe schreiben, die dann die Objekte vom Typ TBankKunde aufnimmt?
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Christian Seehase
(Co-Admin)

Registriert seit: 29. Mai 2002
Ort: Hamburg
11.117 Beiträge
 
Delphi 11 Alexandria
 
#2

Re: Eine Liste von Objekten speichern

  Alt 14. Nov 2006, 17:43
Moin Luckie,

wenn die FKundenliste schon die Objekte vom Typ TBankkunde enthält, müsste

Delphi-Quellcode:
    BankKunde := TBankKunde.Create; // Hier erzeugst Du eine Instanz von TBankkunde
    try
      BankKunde := FKundenListe[i]; // und hier überschreibst Du den Pointer auf das Objekt wieder
      KundenName := BankKunde.Name;
    finally
      BankKunde.Free; // Hier wird das Objekt freigegeben, auf das FKundenListe[i] verweist.
    end;

so aussehen:

Delphi-Quellcode:
    BankKunde := FKundenListe[i];
    KundenName := BankKunde.Name;

    // oder gleich so

    KundenName := FKundenListe[i].Name;
[EDIT]
Analog gilt das dann natürlich auch für die das Hinzufügen von Werten zu der Liste.
Du musst das Objekt erzeugen, aber nicht gleich wieder freigeben (Zeile 64).
Die Freigabe erfolgt dann irgenwann später, wenn Du den Listeninhalt nicht mehr benötigst.
[/EDIT]
Tschüss Chris
Die drei Feinde des Programmierers: Sonne, Frischluft und dieses unerträgliche Gebrüll der Vögel.
Der Klügere gibt solange nach bis er der Dumme ist
  Mit Zitat antworten Zitat
Benutzerbild von DGL-luke
DGL-luke

Registriert seit: 1. Apr 2005
Ort: Bad Tölz
4.149 Beiträge
 
Delphi 2006 Professional
 
#3

Re: Eine Liste von Objekten speichern

  Alt 14. Nov 2006, 17:56
Hallo Luckie,

(verzeih mir, wenn du das alles schon weißt) ein objekt ist erst einmal nur ein zeiger auf einen speicherbereich. geht dir der zeiger verloren, hast du pech gehabt, du kommst wohl nicht mehr ans objekt ran. Wenn du das Objekt also "speichern" willst, wäre eine Möglichkeit, dir zwei Routinen zu schreiben, die das Objekt in einen Stream schreiben bzw. aus ihm lesen. Die RTTI kann das übrigens auch, da musst du nur mal nach Hier im Forum suchenserialisieren suchen.

Ansonsten solltest du verhindern,

a) den Zeiger auf ein Objekt zu verlieren (man kann ihn in einer TList oder besser TObjectlist ablegen, das ganze kann man auch noch typisieren, siehe typisierte Listetypisierte Liste)
b) das Objekt freizugeben, bevor du sicher bist, dass du es nicht mehr brauchst.

Und wo genau hast du jetzt Probleme?

ach ja...

BankKunde := FKundenListe[i]; was willst du da tun? du erstellst einen neuen bankkunden (über TBankkkunde.Create). in Bankkunde liegt dann der zeiger auf dieses objekt. Und jetzt weist du ein element eines mit 0 initalisierten arrays darauf zu... das kann nicht gut enden
Lukas Erlacher
Suche Grafiktablett. Spenden/Gebrauchtangebote willkommen.
Gotteskrieger gesucht!
For it is the chief characteristic of the religion of science that it works. - Isaac Asimov, Foundation I, Buch 1
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#4

Re: Eine Liste von Objekten speichern

  Alt 14. Nov 2006, 18:02
Ah ja gut. Ich habe mich abr entschieden es anders zu machen und zwar mit einer extra Klasse:
Delphi-Quellcode:
type
  TBankKunde = class(TObject)
  private
    FName: String;
    procedure SetName(Name: String);
    function GetName: String;
  public
    property Name: String read GetName write SetName;
  end;

  TBankKundeCollection = class(TList)
  private
    function Get(Index: Integer): TBankKunde;
  public
    procedure Add(Item: TBankKunde);
    property Items[Index: Integer]: TBankKunde read Get;
  end;
Die Klasse TBankKundeCollection soll mir eine Liste der BankKunden verwalten. Aber da habe ich ein Problem mit:
Delphi-Quellcode:
procedure TForm1.UpdateListbox;
var
  i : Integer;
  KundenName : string;
  BankKunde : TBankKunde;
begin
  Listbox1.Clear;
  for i := 0 to FKundenListe.Count - 1 do
  begin
    BankKunde := FKundenListe.Items[i];
    KundenName := BankKunde.Name;
    ListBox1.Items.Add(KundenName);
  end;
  ShowMessage(IntToStr(FKundenListe.Count));
end;

procedure TForm1.btnKundeNeuClick(Sender: TObject);
var
  BankKunde : TBankKunde;
  KundenName : string;
begin
  KundenName := InputBox('Neuer Kunden', 'Name des Kunden:', '');
  BankKunde := TBankKunde.Create;
  try
    try
      BankKunde.Name := KundenName;
      FKundenListe.Add(BankKunde);
    except
      on E: Exception do
        MessageBox(Handle, PChar(E.Message), PChar('Neuen Kunde anlegen'), MB_ICONSTOP);
    end;
  finally
    //BankKunde.Free;
  end;
  UpdateListbox;
end;
In Zeile 33 kann ich das Objekt ja nicht frei geben. Wie gebe ich das am besten frei? Oder wird das automatisch freigegeben, wenn ich die BankKundenCollection (FKundenListe) zerstöre?
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Christian Seehase
(Co-Admin)

Registriert seit: 29. Mai 2002
Ort: Hamburg
11.117 Beiträge
 
Delphi 11 Alexandria
 
#5

Re: Eine Liste von Objekten speichern

  Alt 14. Nov 2006, 18:09
Moin Luckie,

für die Freigabe sollte das Listenobjekt zuständig sein.
Im Destruktor wird die Liste durchgegangen und alle enthaltenen Objekte freigegeben.

Ersatzweise könntest Du auch eine TObjectList nehmen, und hierbie OwnsObjects auf true setzen.
Tschüss Chris
Die drei Feinde des Programmierers: Sonne, Frischluft und dieses unerträgliche Gebrüll der Vögel.
Der Klügere gibt solange nach bis er der Dumme ist
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#6

Re: Eine Liste von Objekten speichern

  Alt 14. Nov 2006, 18:12
So habe ich es jetzt auch gelöst:
Delphi-Quellcode:
procedure TBankKundeCollection.Free;
var
  i : Integer;
begin
  for i := 0 to self.Count - 1 do
    self.Items[i].Free;
end;
Eine TObjectList kennt mein Delphi 6 Personal nicht.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
NormanNG

Registriert seit: 1. Feb 2006
294 Beiträge
 
Delphi 2007 Professional
 
#7

Re: Eine Liste von Objekten speichern

  Alt 14. Nov 2006, 18:13
Hi,

du darfst das Object dort garnicht freigeben. Du hast den Zeiger auf das Objekt in deiner Collection und zusätzlich in Bankkunde. Wenn die nun Bankkunde freigibst, ist der Zeiger ( auf das nun ungültige Objekt) in deiner Collection noch drin. Den kannst du aber nicht mehr verwenden.

Also: Bankkunde beim Neuanlegen nicht freigeben, sondern irgendwann (mit dem Zerstören der Collection).

[edit] roter kasten, aber trotzdem... [/edit]
Gruß
Norman
  Mit Zitat antworten Zitat
shmia

Registriert seit: 2. Mär 2004
5.508 Beiträge
 
Delphi 5 Professional
 
#8

Re: Eine Liste von Objekten speichern

  Alt 14. Nov 2006, 18:24
Zitat von Luckie:
Eine TObjectList kennt mein Delphi 6 Personal nicht.
Uses ...,Contnrs; Also ich bin überzeugter TObjectList Benutzer, weil es die Arbeit sehr erleichtert.
Andreas
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#9

Re: Eine Liste von Objekten speichern

  Alt 14. Nov 2006, 18:28
Die Unit kenne ich noch gar nicht.

Ok, habe es jetzt so gelöst.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:54 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz