[gelöst] Werte vererbt ?!? (Pointerproblem)

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
mulcheo
Beiträge: 57
Registriert: Do 1. Aug 2013, 15:11

[gelöst] Werte vererbt ?!? (Pointerproblem)

Beitrag von mulcheo »

ich hoffe mal, ihr könnt mir helfen; es ist quasi ein Folgeproblem von: http://www.lazarusforum.de/viewtopic.php?f=55&t=7995 ...

Folgendes:

ich weise einer Listbox sukzessive alle Elemente meines Array Kasten (eigene Klase: TKasten) zu, indem:

Code: Alles auswählen

for i:= Low(Kasten) to High(Kasten) do begin
  (...)  // Routinen, die s bilden
  ListBox1.AddItem(s, Kasten[i]);
end;
ich übergebe dann bei der User-Wahl eines dieser Listboxeinträge das Objekt an tmp_Kasten (auch eine Ableitung der Klasse TKasten, jedoch kein Array). Dabei lasse ich mir u.a. einen Wert im Memo ausgeben

Code: Alles auswählen

procedure TForm2.ListBox1SelectionChange(Sender: TObject; User: boolean);
begin
  tmp_Kasten:=TKasten(ListBox1.Items.Objects[ListBox1.ItemIndex]);
  (...)
  Memo1.Text:=tmp_Kasten.Text;
end;
soweit, so gut; jetzt erscheint beim Durchklicken der Listbox (wie gewünscht) im Memo immer der ursprüngliche Eintrag, den ich via Kasten[].Text hinterlegt hatte...

wenn ich nun den Text im Memo von Hand änder und diese Änderung automatisch an tmp_Kasten übergebe...

Code: Alles auswählen

procedure TForm2.Memo1EditingDone(Sender: TObject);
begin
  tmp_Kasten.Text:=TrimRight(Memo1.Text);
end;
ändert sich nicht nur der Wert in tmp_Kasten, sondern auch der ursprüngliche Wert im Array Kasten[]!!!

meine zwei Fragen sind: a) Warum? und b) Wie kann ich das verhindern bzw. die Sache also so drehen, dass (wie in meiner Prozedur TForm2.Memo1EditingDone(Sender: TObject); vorgeshen) nur der tmp_Kasten-Wert sich ändert, das ursprüngliche Array aber unberührt bleibt?
Meine Vermutung ist, dass tmp_Kasten und Kasten[] in einem der Schritte ohne mein Wissen als Pointer aneinander gekoppelt werden... Shice! :(
Zuletzt geändert von mulcheo am Mo 25. Aug 2014, 22:15, insgesamt 1-mal geändert.

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: Werte transitiv vererbt ?!? (Pointerproblem)

Beitrag von Michl »

Mit

Code: Alles auswählen

  tmp_Kasten:=TKasten(ListBox1.Items.Objects[ListBox1.ItemIndex]);
übergibst Du das Objekt (also den Zeiger auf dieses). Damit zeigen beide Einträge auf ein- und die selbe Stelle im Speicher.

Um dem aus dem Weg zu gehen, müsstest Du einen neuen tmp_Kasten erstellen (z.B. bei Form.OnCreate, wenn global oder in TForm1 deklariert) und nur den Inhalt des Objekts übergeben (nicht das Objekt!) z.B:

Code: Alles auswählen

procedure TForm2.ListBox1SelectionChange(Sender: TObject; User: boolean);
begin
  tmp_Kasten.Text:=TKasten(ListBox1.Items.Objects[ListBox1.ItemIndex]).Text;
  (...)
end;

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

baumina
Beiträge: 152
Registriert: Mo 3. Feb 2014, 14:07
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit

Re: Werte transitiv vererbt ?!? (Pointerproblem)

Beitrag von baumina »

Durch

Code: Alles auswählen

tmp_Kasten:=TKasten(ListBox1.Items.Objects[ListBox1.ItemIndex]);
erhältst du keine Kopie, sondern zeigst einfach auch nur dort hin wo das Object der Listbox rumliegt.

Um eine Kopie der Daten zu erhalten, müsstest Du das so machen:

Code: Alles auswählen

tmp_Kasten := TKasten.Create;
tmp_Kasten.Assign(TKasten(ListBox1.Items.Objects[ListBox1.ItemIndex]);
Sollte deine Klasse TKasten kein Assign kennen, müsstest du dieses allerdings vorher der Klasse beibringen.
.

mulcheo
Beiträge: 57
Registriert: Do 1. Aug 2013, 15:11

Re: Werte transitiv vererbt ?!? (Pointerproblem)

Beitrag von mulcheo »

dann hat sich mein Verdacht also bestätigt. Michls Lösung funktioniert auch - danke.

@Baumina: kurze Rückfrage noch zum Verständnis; meine Klasse hat kein assign - meinst du damit etwa das, was Michl vorgeschlagen hat? ODer wie sollte ich ein passendes assign implementieren?

Benutzeravatar
theo
Beiträge: 10869
Registriert: Mo 11. Sep 2006, 19:01

Re: Werte transitiv vererbt ?!? (Pointerproblem)

Beitrag von theo »

b.Assign(a);

Assign Ist eine Prozdeur, welche alle Eigenschaften von a auf b kopiert.

Für eine eigene Klasse muss man das natürlich auch selber programmieren.

Antworten